From 4acb40c03ed288bb397bb2260f854a319fffcc01 Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Wed, 10 Apr 2013 02:20:35 -0300 Subject: [PATCH 01/31] Basic support for building the MPFR --- deps/.gitignore | 1 + deps/Makefile | 46 ++++++++++++++++++++++++++++++++++++++++++++-- deps/Versions.make | 1 + 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/deps/.gitignore b/deps/.gitignore index ac2b0f8b7af17..86ee7cfaca893 100644 --- a/deps/.gitignore +++ b/deps/.gitignore @@ -15,6 +15,7 @@ /libunwind-* /lighttpd-* /llvm-* +/mpfr-* /openblas-* /patchelf-* /pcre-* diff --git a/deps/Makefile b/deps/Makefile index e05965117d0d8..493dcdfc78d7c 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -21,7 +21,7 @@ ifeq ($(OS),WINNT) CONFIGURE_COMMON += LDFLAGS=-Wl,--stack,8388608 endif -#autoconf configure-driven scripts: llvm readline pcre arpack fftw unwind gmp patchelf +#autoconf configure-driven scripts: llvm readline pcre arpack fftw unwind gmp mpfr patchelf #custom configure-driven script: zlib #custom Makefile rules: openlibm Rmath double-conversion random suitesparse-wrapper suitesparse lapack openblas uv @@ -102,6 +102,10 @@ endif #STAGE1_DEPS += zlib #endif +ifeq ($(USE_SYSTEM_MPFR), 0) +STAGE1_DEPS += mpfr +endif + ifeq ($(USE_SYSTEM_ARPACK), 0) STAGE2_DEPS += arpack endif @@ -134,7 +138,7 @@ install: $(addprefix install-, $(LIBS)) cleanall: $(addprefix clean-, $(LIBS)) distclean: $(addprefix distclean-, $(LIBS)) rm -rf $(BUILD) -getall: get-llvm get-readline get-uv get-pcre get-double-conversion get-openlibm get-random get-openblas get-fftw get-suitesparse get-unwind get-gmp get-zlib get-patchelf +getall: get-llvm get-readline get-uv get-pcre get-double-conversion get-openlibm get-random get-openblas get-fftw get-suitesparse get-unwind get-gmp get-mpfr get-zlib get-patchelf ## PATHS ## DIRS = $(addprefix $(BUILD)/,lib include bin share etc) @@ -1182,6 +1186,44 @@ compile-gmp: $(GMP_SRC_TARGET) check-gmp: gmp-$(GMP_VER)/checked install-gmp: $(GMP_OBJ_TARGET) +## MPFR ## + +MPFR_SRC_TARGET = mpfr-$(MPFR_VER)/.libs/libmpfr.$(SHLIB_EXT) +MPFR_OBJ_TARGET = $(BUILD)/lib/libmpfr.$(SHLIB_EXT) + +mpfr-$(MPFR_VER).tar.bz2: + $(WGET_DASH_O) $@ http://www.mpfr.org/mpfr-current/$@ +mpfr-$(MPFR_VER)/configure: mpfr-$(MPFR_VER).tar.bz2 + tar jxf $< + touch -c $@ +mpfr-$(MPFR_VER)/config.status: mpfr-$(MPFR_VER)/configure + cd mpfr-$(MPFR_VER) && \ + ./configure $(CONFIGURE_COMMON) F77= --enable-shared --disable-static + touch -c $@ +$(MPFR_SRC_TARGET): mpfr-$(MPFR_VER)/config.status + $(MAKE) -C mpfr-$(MPFR_VER) $(LIBTOOL_CCLD) +mpfr-$(MPFR_VER)/checked: $(MPFR_SRC_TARGET) +ifeq ($(OS),$(BUILD_OS)) + $(MAKE) -C mpfr-$(MPFR_VER) $(LIBTOOL_CCLD) check +endif + echo 1 > $@ +$(MPFR_OBJ_TARGET): $(MPFR_SRC_TARGET) mpfr-$(MPFR_VER)/checked + $(MAKE) -C mpfr-$(MPFR_VER) $(LIBTOOL_CCLD) install + $(INSTALL_NAME_CMD)libmpfr.dylib $@ + touch -c $@ + +clean-mpfr: + -$(MAKE) -C mpfr-$(MPFR_VER) clean + -rm -f $(MPFR_OBJ_TARGET) +distclean-mpfr: + -rm -rf mpfr-$(MPFR_VER).tar.bz2 mpfr-$(MPFR_VER) + +get-mpfr: mpfr-$(MPFR_VER).tar.bz2 +configure-mpfr: mpfr-$(MPFR_VER)/config.status +compile-mpfr: $(MPFR_SRC_TARGET) +check-mpfr: mpfr-$(MPFR_VER)/checked +install-mpfr: $(MPFR_OBJ_TARGET) + ## ZLIB ## ifeq ($(OS),WINNT) diff --git a/deps/Versions.make b/deps/Versions.make index a1854bb3c9c7d..0480610a58c94 100644 --- a/deps/Versions.make +++ b/deps/Versions.make @@ -11,6 +11,7 @@ FFTW_VER = 3.3.3 SUITESPARSE_VER = 4.2.0 UNWIND_VER = 1.1 GMP_VER=5.1.1 +MPFR_VER=3.1.2 ZLIB_VER = 1.2.7 PATCHELF_VER = 0.6 GIT_VER = 1.8.2.1 From 9853f7f117696fab54702acc42cb4ef6207c43db Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Wed, 10 Apr 2013 02:34:41 -0300 Subject: [PATCH 02/31] Add more mentions to the MPFR on the build system and documentation --- .travis.yml | 2 +- LICENSE.md | 1 + Make.inc | 1 + Makefile | 2 +- README.md | 2 ++ 5 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a77e76ffe2354..7785b59a1c142 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ compiler: notifications: email: false before_install: - - BUILDOPTS="LLVM_CONFIG=llvm-config-3.2 USE_QUIET=0 USE_LIB64=0"; for lib in LLVM ZLIB SUITESPARSE ARPACK BLAS FFTW LAPACK GMP PCRE LIBUNWIND READLINE GRISU OPENLIBM RMATH LIBUV; do export BUILDOPTS="$BUILDOPTS USE_SYSTEM_$lib=1"; done + - BUILDOPTS="LLVM_CONFIG=llvm-config-3.2 USE_QUIET=0 USE_LIB64=0"; for lib in LLVM ZLIB SUITESPARSE ARPACK BLAS FFTW LAPACK GMP MPFR PCRE LIBUNWIND READLINE GRISU OPENLIBM RMATH LIBUV; do export BUILDOPTS="$BUILDOPTS USE_SYSTEM_$lib=1"; done - sudo apt-get update -qq -y - sudo apt-get install zlib1g-dev - sudo add-apt-repository ppa:staticfloat/julia-deps -y diff --git a/LICENSE.md b/LICENSE.md index 7f58931c0a54b..fb06837f22f72 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -58,6 +58,7 @@ External libraries, if used, include their own licenses: - [LAPACK](http://netlib.org/lapack/LICENSE.txt) - [LIBUNWIND](http://git.savannah.gnu.org/gitweb/?p=libunwind.git;a=blob_plain;f=LICENSE;hb=master) - [LLVM](http://llvm.org/releases/3.0/LICENSE.TXT) +- [MPFR](http://www.mpfr.org/mpfr-current/mpfr.html#Copying) - [OPENBLAS](https://raw.github.com/xianyi/OpenBLAS/master/LICENSE) - [PCRE](http://www.pcre.org/licence.txt) - [READLINE](http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html) diff --git a/Make.inc b/Make.inc index 8b781055b59f3..99c380f50ab19 100644 --- a/Make.inc +++ b/Make.inc @@ -163,6 +163,7 @@ USE_SYSTEM_BLAS=0 USE_SYSTEM_LAPACK=0 USE_SYSTEM_FFTW=0 USE_SYSTEM_GMP=0 +USE_SYSTEM_MPFR=0 USE_SYSTEM_ARPACK=0 USE_SYSTEM_SUITESPARSE=0 USE_SYSTEM_ZLIB=0 diff --git a/Makefile b/Makefile index 37c1777a3bda7..b5b4bd7c39c3c 100644 --- a/Makefile +++ b/Makefile @@ -66,7 +66,7 @@ JL_PRIVATE_LIBS = amd arpack camd ccolamd cholmod colamd \ fftw3 fftw3f fftw3_threads fftw3f_threads \ gmp grisu openlibm openlibm-extras pcre \ random Rmath spqr suitesparse_wrapper \ - umfpack z openblas + umfpack z openblas mpfr PREFIX ?= julia-$(JULIA_COMMIT) install: diff --git a/README.md b/README.md index 0d756c88326ef..2b1cc09b5ad55 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,7 @@ Julia uses the following external libraries, which are automatically downloaded - **[FFTW]** — library for computing fast Fourier transforms very quickly and efficiently. - **[PCRE]** — Perl-compatible regular expressions library. - **[GMP]** — the GNU multiple precision arithmetic library, needed for bigint support. +- **[MPFR]** — the GNU multiple precision floating point library, needed for bigfloat support. - **[double-conversion]** — efficient number-to-text conversion. - **[Rmath]** — basic RNGs and distributions. @@ -179,6 +180,7 @@ Julia uses the following external libraries, which are automatically downloaded [FemtoLisp]: https://github.com/JeffBezanson/femtolisp [readline]: http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html [GMP]: http://gmplib.org/ +[MPFR]: http://www.mpfr.org/ [double-conversion]: http://double-conversion.googlecode.com/ [Rmath]: http://cran.r-project.org/doc/manuals/R-admin.html#The-standalone-Rmath-library [libuv]: https://github.com/JuliaLang/libuv From 6762def975756b1bbf72610c991b58131a43385c Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Wed, 10 Apr 2013 11:33:21 -0300 Subject: [PATCH 03/31] Add mpc to the build system and basic documentation --- .travis.yml | 2 +- LICENSE.md | 1 + Make.inc | 1 + Makefile | 8 ++++++++ README.md | 4 +++- deps/.gitignore | 1 + deps/Makefile | 46 ++++++++++++++++++++++++++++++++++++++++++++-- deps/Versions.make | 1 + 8 files changed, 60 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7785b59a1c142..1f83af06ae8da 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ compiler: notifications: email: false before_install: - - BUILDOPTS="LLVM_CONFIG=llvm-config-3.2 USE_QUIET=0 USE_LIB64=0"; for lib in LLVM ZLIB SUITESPARSE ARPACK BLAS FFTW LAPACK GMP MPFR PCRE LIBUNWIND READLINE GRISU OPENLIBM RMATH LIBUV; do export BUILDOPTS="$BUILDOPTS USE_SYSTEM_$lib=1"; done + - BUILDOPTS="LLVM_CONFIG=llvm-config-3.2 USE_QUIET=0 USE_LIB64=0"; for lib in LLVM ZLIB SUITESPARSE ARPACK BLAS FFTW LAPACK GMP MPFR MPC PCRE LIBUNWIND READLINE GRISU OPENLIBM RMATH LIBUV; do export BUILDOPTS="$BUILDOPTS USE_SYSTEM_$lib=1"; done - sudo apt-get update -qq -y - sudo apt-get install zlib1g-dev - sudo add-apt-repository ppa:staticfloat/julia-deps -y diff --git a/LICENSE.md b/LICENSE.md index fb06837f22f72..b574e102095ab 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -58,6 +58,7 @@ External libraries, if used, include their own licenses: - [LAPACK](http://netlib.org/lapack/LICENSE.txt) - [LIBUNWIND](http://git.savannah.gnu.org/gitweb/?p=libunwind.git;a=blob_plain;f=LICENSE;hb=master) - [LLVM](http://llvm.org/releases/3.0/LICENSE.TXT) +- [MPC](http://www.multiprecision.org/index.php?prog=mpc&page=html#Copying) - [MPFR](http://www.mpfr.org/mpfr-current/mpfr.html#Copying) - [OPENBLAS](https://raw.github.com/xianyi/OpenBLAS/master/LICENSE) - [PCRE](http://www.pcre.org/licence.txt) diff --git a/Make.inc b/Make.inc index 99c380f50ab19..cf5c3396d9dd8 100644 --- a/Make.inc +++ b/Make.inc @@ -164,6 +164,7 @@ USE_SYSTEM_LAPACK=0 USE_SYSTEM_FFTW=0 USE_SYSTEM_GMP=0 USE_SYSTEM_MPFR=0 +USE_SYSTEM_MPC=0 USE_SYSTEM_ARPACK=0 USE_SYSTEM_SUITESPARSE=0 USE_SYSTEM_ZLIB=0 diff --git a/Makefile b/Makefile index b5b4bd7c39c3c..5acc8b1428340 100644 --- a/Makefile +++ b/Makefile @@ -62,11 +62,19 @@ run-julia: JL_LIBS = julia-release julia-debug # private libraries, that are installed in $(PREFIX)/lib/julia +<<<<<<< HEAD JL_PRIVATE_LIBS = amd arpack camd ccolamd cholmod colamd \ fftw3 fftw3f fftw3_threads fftw3f_threads \ gmp grisu openlibm openlibm-extras pcre \ random Rmath spqr suitesparse_wrapper \ umfpack z openblas mpfr +======= +JL_PRIVATE_LIBS = amd arpack cholmod colamd fftw3 fftw3f fftw3_threads \ + fftw3f_threads gmp grisu mpfr mpc \ + openlibm openlibm-extras pcre \ + random Rmath spqr suitesparse_wrapper \ + umfpack z openblas +>>>>>>> Add mpc to the build system and basic documentation PREFIX ?= julia-$(JULIA_COMMIT) install: diff --git a/README.md b/README.md index 2b1cc09b5ad55..f1fd88df41360 100644 --- a/README.md +++ b/README.md @@ -152,7 +152,8 @@ Julia uses the following external libraries, which are automatically downloaded - **[FFTW]** — library for computing fast Fourier transforms very quickly and efficiently. - **[PCRE]** — Perl-compatible regular expressions library. - **[GMP]** — the GNU multiple precision arithmetic library, needed for bigint support. -- **[MPFR]** — the GNU multiple precision floating point library, needed for bigfloat support. +- **[MPFR]** — the GNU multiple precision floating point library, needed for arbitrary precision floating point support. +- **[MPC]** — the GNU multiple precision complex arithmetic library, needed for arbitrary precision complex number support. - **[double-conversion]** — efficient number-to-text conversion. - **[Rmath]** — basic RNGs and distributions. @@ -181,6 +182,7 @@ Julia uses the following external libraries, which are automatically downloaded [readline]: http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html [GMP]: http://gmplib.org/ [MPFR]: http://www.mpfr.org/ +[MPC]: http://www.multiprecision.org/ [double-conversion]: http://double-conversion.googlecode.com/ [Rmath]: http://cran.r-project.org/doc/manuals/R-admin.html#The-standalone-Rmath-library [libuv]: https://github.com/JuliaLang/libuv diff --git a/deps/.gitignore b/deps/.gitignore index 86ee7cfaca893..1957599abeaa6 100644 --- a/deps/.gitignore +++ b/deps/.gitignore @@ -15,6 +15,7 @@ /libunwind-* /lighttpd-* /llvm-* +/mpc-* /mpfr-* /openblas-* /patchelf-* diff --git a/deps/Makefile b/deps/Makefile index 493dcdfc78d7c..1f8450fe9adf4 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -21,7 +21,7 @@ ifeq ($(OS),WINNT) CONFIGURE_COMMON += LDFLAGS=-Wl,--stack,8388608 endif -#autoconf configure-driven scripts: llvm readline pcre arpack fftw unwind gmp mpfr patchelf +#autoconf configure-driven scripts: llvm readline pcre arpack fftw unwind gmp mpfr mpc patchelf #custom configure-driven script: zlib #custom Makefile rules: openlibm Rmath double-conversion random suitesparse-wrapper suitesparse lapack openblas uv @@ -106,6 +106,10 @@ ifeq ($(USE_SYSTEM_MPFR), 0) STAGE1_DEPS += mpfr endif +ifeq ($(USE_SYSTEM_MPC), 0) +STAGE1_DEPS += mpc +endif + ifeq ($(USE_SYSTEM_ARPACK), 0) STAGE2_DEPS += arpack endif @@ -138,7 +142,7 @@ install: $(addprefix install-, $(LIBS)) cleanall: $(addprefix clean-, $(LIBS)) distclean: $(addprefix distclean-, $(LIBS)) rm -rf $(BUILD) -getall: get-llvm get-readline get-uv get-pcre get-double-conversion get-openlibm get-random get-openblas get-fftw get-suitesparse get-unwind get-gmp get-mpfr get-zlib get-patchelf +getall: get-llvm get-readline get-uv get-pcre get-double-conversion get-openlibm get-random get-openblas get-fftw get-suitesparse get-unwind get-gmp get-mpfr get-mpc get-zlib get-patchelf ## PATHS ## DIRS = $(addprefix $(BUILD)/,lib include bin share etc) @@ -1224,6 +1228,44 @@ compile-mpfr: $(MPFR_SRC_TARGET) check-mpfr: mpfr-$(MPFR_VER)/checked install-mpfr: $(MPFR_OBJ_TARGET) +## MPC ## + +MPC_SRC_TARGET = mpc-$(MPC_VER)/.libs/libmpc.$(SHLIB_EXT) +MPC_OBJ_TARGET = $(BUILD)/lib/libmpc.$(SHLIB_EXT) + +mpc-$(MPC_VER).tar.gz: + $(WGET_DASH_O) $@ http://www.multiprecision.org/mpc/download/$@ +mpc-$(MPC_VER)/configure: mpc-$(MPC_VER).tar.gz + tar zxf $< + touch -c $@ +mpc-$(MPC_VER)/config.status: mpc-$(MPC_VER)/configure + cd mpc-$(MPC_VER) && \ + ./configure $(CONFIGURE_COMMON) F77= --enable-shared --disable-static + touch -c $@ +$(MPC_SRC_TARGET): mpc-$(MPC_VER)/config.status + $(MAKE) -C mpc-$(MPC_VER) $(LIBTOOL_CCLD) +mpc-$(MPC_VER)/checked: $(MPC_SRC_TARGET) +ifeq ($(OS),$(BUILD_OS)) + $(MAKE) -C mpc-$(MPC_VER) $(LIBTOOL_CCLD) check +endif + echo 1 > $@ +$(MPC_OBJ_TARGET): $(MPC_SRC_TARGET) mpc-$(MPC_VER)/checked + $(MAKE) -C mpc-$(MPC_VER) $(LIBTOOL_CCLD) install + $(INSTALL_NAME_CMD)libmpc.dylib $@ + touch -c $@ + +clean-mpc: + -$(MAKE) -C mpc-$(MPC_VER) clean + -rm -f $(MPC_OBJ_TARGET) +distclean-mpc: + -rm -rf mpc-$(MPC_VER).tar.gz mpc-$(MPC_VER) + +get-mpc: mpc-$(MPC_VER).tar.gz +configure-mpc: mpc-$(MPC_VER)/config.status +compile-mpc: $(MPC_SRC_TARGET) +check-mpc: mpc-$(MPC_VER)/checked +install-mpc: $(MPC_OBJ_TARGET) + ## ZLIB ## ifeq ($(OS),WINNT) diff --git a/deps/Versions.make b/deps/Versions.make index 0480610a58c94..06a464c53bd51 100644 --- a/deps/Versions.make +++ b/deps/Versions.make @@ -12,6 +12,7 @@ SUITESPARSE_VER = 4.2.0 UNWIND_VER = 1.1 GMP_VER=5.1.1 MPFR_VER=3.1.2 +MPC_VER = 1.0.1 ZLIB_VER = 1.2.7 PATCHELF_VER = 0.6 GIT_VER = 1.8.2.1 From e0ec4097d2f5293f2c9e6277b6c88529345e14cd Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Wed, 10 Apr 2013 14:36:26 -0300 Subject: [PATCH 04/31] Add MPC and MPFR to Base Both MPC and MPFR are building correctly and running all tests (the same I had when they were a different package). Currently, the biggest issue is that `make check` for MPFR and MPC run all their tests, considerably lengthening the build process. --- base/exports.jl | 15 ++ base/mpc.jl | 263 ++++++++++++++++++++++++++++ base/mpfr.jl | 445 +++++++++++++++++++++++++++++++++++++++++++++++ base/sysimg.jl | 6 + test/mpc.jl | 65 +++++++ test/mpfr.jl | 306 ++++++++++++++++++++++++++++++++ test/runtests.jl | 2 +- 7 files changed, 1101 insertions(+), 1 deletion(-) create mode 100644 base/mpc.jl create mode 100644 base/mpfr.jl create mode 100644 test/mpc.jl create mode 100644 test/mpfr.jl diff --git a/base/exports.jl b/base/exports.jl index 5f3dfc083e154..16df377045381 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -9,6 +9,8 @@ export LibRandom, Random, Math, + MPC, + MPFR, GMP, Sort, Test, @@ -56,6 +58,8 @@ export IntSet, LocalProcess, Matrix, + MPCComplex, + MPFRFloat, ObjectIdDict, #Pipe, #PipeEnd, @@ -820,6 +824,17 @@ export randn, srand, +# precision + exp10, + prec, + prec2, + get_precision, + get_complex_precision, + set_precision, + set_complex_precision, + with_precision, + with_complex_precision, + # statistics cor, cov, diff --git a/base/mpc.jl b/base/mpc.jl new file mode 100644 index 0000000000000..c6b05f2a5de02 --- /dev/null +++ b/base/mpc.jl @@ -0,0 +1,263 @@ +module MPC + +export + # Types + MPCComplex, + # Functions + prec2, + get_complex_precision, + set_complex_precision, + with_complex_precision + +import + Base: (*), +, -, /, <, <<, >>, <=, ==, >, >=, ^, (~), (&), (|), ($), cmp, + complex, convert, div, imag, integer_valued, isfinite, isinf, isnan, + promote_rule, real, show, showcompact, sqrt, string, prec + +const ROUNDING_MODE = 0 +const DEFAULT_PRECISION = [53, 53] + +# Basic type and initialization definitions + +immutable MPCComplex{N,P} <: Number + mpc::Vector{Int32} + function MPCComplex() + if N < 2 || P < 2 + error("Invalid precision") + end + z = Array(Int32, 16) + ccall((:mpc_init3,:libmpc), Void, (Ptr{Void}, Int32, Int32), z, N, P) + b = new(z) + finalizer(b.mpc, MPC_clear) + return b + end +end + +MPC_clear(mpc::Vector{Int32}) = ccall((:mpc_clear, :libmpc), Void, (Ptr{Void},), mpc) + +function MPCComplex{N,P}(x::MPCComplex{N,P}) + z = MPCComplex{N,P}() + ccall((:mpc_set, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpc, ROUNDING_MODE) + return z +end + +# Real constructors +for (fJ, fC) in ((:si,:Int), (:ui,:Uint), (:d,:Float64)) + @eval begin + function MPCComplex(x::($fC)) + z = MPCComplex{DEFAULT_PRECISION[1], DEFAULT_PRECISION[end]}() + ccall(($(string(:mpc_set_,fJ)), :libmpc), Int32, (Ptr{Void}, ($fC), Int32), z.mpc, x, ROUNDING_MODE) + return z + end + end +end + +function MPCComplex(x::BigInt) + z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() + ccall((:mpc_set_z, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpz, ROUNDING_MODE) + return z +end + +function MPCComplex(x::BigFloat) + z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() + ccall((:mpc_set_f, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpf, ROUNDING_MODE) + return z +end + +function MPCComplex(x::MPFRFloat) + z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() + ccall((:mpc_set_fr, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpfr, ROUNDING_MODE) + return z +end + +function MPCComplex(x::String, base::Int) + z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() + err = ccall((:mpc_set_str, :libmpc), Int32, (Ptr{Void}, Ptr{Uint8}, Int32, Int32), z.mpc, x, base, ROUNDING_MODE) + if err != 0; error("Invalid input"); end + return z +end +MPCComplex(x::String) = MPCComplex(x, 10) + +MPCComplex(x::Bool) = MPCComplex(uint(x)) +MPCComplex(x::Signed) = MPCComplex(int(x)) +MPCComplex(x::Unsigned) = MPCComplex(uint(x)) +if WORD_SIZE == 32 + MPCComplex(x::Int64) = MPCComplex(BigInt(x)) + MPCComplex(x::Uint64) = MPCComplex(BigInt(x)) +end +MPCComplex(x::Float32) = MPCComplex(float64(x)) +MPCComplex(x::Rational) = MPCComplex(num(x)) / MPCComplex(den(x)) + +# TODO: fix the precision support here +convert{N,P}(::Type{MPCComplex{N,P}}, x::Rational) = MPCComplex(x) # to resolve ambiguity +convert{N,P}(::Type{MPCComplex{N,P}}, x::Real) = MPCComplex(x) +convert(::Type{MPCComplex}, x::Real) = MPCComplex(x) +convert{N,P}(::Type{MPCComplex{N,P}}, x::Complex) = MPCComplex(x) +convert(::Type{MPCComplex}, x::Complex) = MPCComplex(x) +convert{N,P}(::Type{MPCComplex{N,P}}, x::ImaginaryUnit) = MPCComplex(x) +convert(::Type{MPCComplex}, x::ImaginaryUnit) = MPCComplex(x) + +convert(::Type{Float64}, x::MPCComplex) = ccall((:mpc_get_d,:libmpc), Float64, (Ptr{Void},), x.mpc) +convert(::Type{Float32}, x::MPCComplex) = ccall((:mpc_get_flt,:libmpc), Float32, (Ptr{Void},), x.mpc) +#convert(::Type{FloatingPoint}, x::BigInt) = MPCComplex(x) + +promote_rule{T<:Real,N,P}(::Type{MPCComplex{N,P}}, ::Type{T}) = MPCComplex{N,P} +promote_rule{T<:Real}(::Type{MPCComplex}, ::Type{T}) = MPCComplex +promote_rule{T<:Real,N,P}(::Type{MPCComplex{N,P}}, ::Type{Complex{T}}) = MPCComplex{N,P} +promote_rule{T<:Real}(::Type{MPCComplex}, ::Type{Complex{T}}) = MPCComplex +promote_rule{T<:Number,N,P}(::Type{MPCComplex{N,P}}, ::Type{T}) = MPCComplex{N,P} +promote_rule{T<:Number}(::Type{MPCComplex}, ::Type{T}) = MPCComplex +promote_rule{N,P}(::Type{MPCComplex{N,P}}, ::Type{ImaginaryUnit}) = MPCComplex{N,P} +promote_rule(::Type{MPCComplex}, ::Type{ImaginaryUnit}) = MPCComplex + +# TODO: Decide if overwriting the default BigFloat rule is good +#promote_rule{T<:FloatingPoint}(::Type{BigInt},::Type{T}) = MPCComplex +#promote_rule{T<:FloatingPoint,N,P}(::Type{BigFloat},::Type{T}) = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]} + +# Complex constructors +for (fJ, fC) in ((:si,:Int), (:ui,:Uint), (:d,:Float64)) + @eval begin + function MPCComplex(x::($fC), y::($fC)) + z = MPCComplex{DEFAULT_PRECISION[1], DEFAULT_PRECISION[end]}() + ccall(($(string(:mpc_set_,fJ,'_',fJ)), :libmpc), Int32, (Ptr{Void}, ($fC), ($fC), Int32), z.mpc, x, y, ROUNDING_MODE) + return z + end + end +end + +function MPCComplex(x::BigInt, y::BigInt) + z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() + ccall((:mpc_set_z_z, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpz, y.mpz, ROUNDING_MODE) + return z +end + +function MPCComplex(x::BigFloat, y::BigFloat) + z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() + ccall((:mpc_set_f_f, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpf, y.mpf, ROUNDING_MODE) + return z +end + +function MPCComplex(x::MPFRFloat, y::MPFRFloat) + z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() + ccall((:mpc_set_fr_fr, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpfr, y.mpfr, ROUNDING_MODE) + return z +end + +MPCComplex(x::Complex) = MPCComplex(real(x), imag(x)) +MPCComplex(x::ImaginaryUnit) = MPCComplex(1im) +MPCComplex(x::Bool, y::Bool) = MPCComplex(uint(x), uint(y)) +MPCComplex(x::Signed, y::Signed) = MPCComplex(int(x), int(y)) +MPCComplex(x::Unsigned, y::Unsigned) = MPCComplex(uint(x), uint(y)) +if WORD_SIZE == 32 + MPCComplex(x::Int64, y::Int64) = MPCComplex(BigInt(x), BigInt(y)) + MPCComplex(x::Uint64, y::Uint64) = MPCComplex(BigInt(x), BigInt(y)) +end +MPCComplex(x::Float32, y::Float32) = MPCComplex(float64(x), float64(y)) +MPCComplex(x::Rational, y::Rational) = MPCComplex(MPFRFloat(num(x))/MPFRFloat(den(x)), + MPFRFloat(num(y))/MPFRFloat(den(y))) + +# Basic operations + +for (fJ, fC) in ((:+,:add), (:-,:sub), (:*,:mul), (:/,:div), (:^, :pow)) + @eval begin + function ($fJ)(x::MPCComplex, y::MPCComplex) + z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() + ccall(($(string(:mpc_,fC)),:libmpc), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpc, y.mpc, ROUNDING_MODE) + return z + end + end +end + +function -(x::MPCComplex) + z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() + ccall((:mpc_neg, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpc, ROUNDING_MODE) + return z +end + +function cmp(x::MPCComplex, y::MPCComplex) + ccall((:mpc_cmp, :libmpc), Int32, (Ptr{Void}, Ptr{Void}), x.mpc, y.mpc) +end + +function sqrt(x::MPCComplex) + z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() + ccall((:mpc_sqrt, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpc, ROUNDING_MODE) + if isnan(z) + throw(DomainError()) + end + return z +end + +function ^(x::MPCComplex, y::Uint) + z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() + ccall((:mpc_pow_ui, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Uint, Int32), z.mpc, x.mpc, y, ROUNDING_MODE) + return z +end + +function ^(x::MPCComplex, y::Int) + z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() + ccall((:mpc_pow_si, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int, Int32), z.mpc, x.mpc, y, ROUNDING_MODE) + return z +end + +function ^(x::MPCComplex, y::BigInt) + z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() + ccall((:mpc_pow_z, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpc, y.mpz, ROUNDING_MODE) + return z +end + +# Utility functions +==(x::MPCComplex, y::MPCComplex) = ccall((:mpc_cmp, :libmpc), Int32, (Ptr{Void}, Ptr{Void}), x.mpc, y.mpc) == 0 + + +# TODO: decide if prec and prec2 should be just one method or not. +function prec(x::MPCComplex) + return ccall((:mpc_get_prec, :libmpc), Int, (Ptr{Void},), x.mpc) +end + +function prec2(x::MPCComplex) + a = [0] + b = [0] + ccall((:mpc_get_prec2, :libmpc), Int, (Ptr{Int}, Ptr{Int}, Ptr{Void}), a, b, x.mpc) + return (a[1],b[1]) +end + +get_complex_precision() = (DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]) +function set_complex_precision(x::Int, y::Int) + if x < 2 + throw(DomainError()) + end + DEFAULT_PRECISION[1], DEFAULT_PRECISION[end] = x, y +end +set_complex_precision(x::(Int,Int)) = set_complex_precision(x...) + +iscomplex(::MPCComplex) = true +isfinite(x::MPCComplex) = isfinite(real(x)) && isfinite(imag(x)) +isinf(x::MPCComplex) = !isfinite(x) +integer_valued(x::MPCComplex) = imag(x) == 0 && integer_valued(real(x)) + +function with_complex_precision(f::Function, realprec::Integer, imagprec::Integer) + old_precision = get_complex_precision() + set_complex_precision(realprec, imagprec) + ret = f() + set_complex_precision(old_precision) + return ret +end + +function imag{N,P}(x::MPCComplex{N,P}) + z = MPFRFloat{N}() + ccall((:mpc_imag, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpc, ROUNDING_MODE) + return z +end + +function real{N,P}(x::MPCComplex{N,P}) + z = MPFRFloat{N}() + ccall((:mpc_real, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpc, ROUNDING_MODE) + return z +end + +string(x::MPCComplex) = "$(string(real(x))) + $(string(imag(x)))im" + +show(io::IO, b::MPCComplex) = print(io, string(b) * " with $(prec2(b)) bits of precision") +showcompact(io::IO, b::MPCComplex) = print(io, string(b)) + +end #module diff --git a/base/mpfr.jl b/base/mpfr.jl new file mode 100644 index 0000000000000..fdf3735f00f8d --- /dev/null +++ b/base/mpfr.jl @@ -0,0 +1,445 @@ +module MPFR + +export + # Types + MPFRFloat, + # Functions + exp10, + prec, + get_precision, + set_precision, + with_precision + +import + Base: (*), +, -, /, <, <=, ==, >, >=, ^, besselj, besselj0, besselj1, + bessely, bessely0, bessely1, ceil, cmp, convert, copysign, exp, exp2, + exponent, factorial, floor, integer_valued, iround, isfinite, isinf, + isnan, log, log2, log10, max, min, mod, modf, nextfloat, prevfloat, + promote_rule, rem, round, show, showcompact, sum, sqrt, string, trunc, + # import trigonometric functions + sin, cos, tan, sec, csc, cot, acos, asin, atan, cosh, sinh, tanh, + sech, csch, coth, acosh, asinh, atanh + +const ROUNDING_MODE = [0] +const DEFAULT_PRECISION = [53, 53] + +# Basic type and initialization definitions + +immutable MPFRFloat{N} <: FloatingPoint + mpfr::Vector{Int32} + function MPFRFloat() + if N < 2 + error("Invalid precision") + end + z = Array(Int32, 5) + ccall((:mpfr_init2,:libmpfr), Void, (Ptr{Void}, Int), z, N) + b = new(z) + finalizer(b.mpfr, MPFR_clear) + return b + end +end + +MPFR_clear(mpfr::Vector{Int32}) = ccall((:mpfr_clear, :libmpfr), Void, (Ptr{Void},), mpfr) + +function MPFRFloat(x::MPFRFloat) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_set, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + return z +end + +for (fJ, fC) in ((:si,:Int), (:ui,:Uint), (:d,:Float64)) + @eval begin + function MPFRFloat(x::($fC)) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall(($(string(:mpfr_set_,fJ)), :libmpfr), Int32, (Ptr{Void}, ($fC), Int32), z.mpfr, x, ROUNDING_MODE[end]) + return z + end + end +end + +function MPFRFloat(x::BigInt) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_set_z, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpz, ROUNDING_MODE[end]) + return z +end + +function MPFRFloat(x::BigFloat) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_set_f, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpf, ROUNDING_MODE[end]) + return z +end + +function MPFRFloat(x::String, base::Int) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + err = ccall((:mpfr_set_str, :libmpfr), Int32, (Ptr{Void}, Ptr{Uint8}, Int32, Int32), z.mpfr, x, base, ROUNDING_MODE[end]) + if err != 0; error("Invalid input"); end + return z +end +MPFRFloat(x::String) = MPFRFloat(x, 10) + + +MPFRFloat(x::Bool) = MPFRFloat(uint(x)) +MPFRFloat(x::Signed) = MPFRFloat(int(x)) +MPFRFloat(x::Unsigned) = MPFRFloat(uint(x)) +if WORD_SIZE == 32 + MPFRFloat(x::Int64) = MPFRFloat(string(x)) + MPFRFloat(x::Uint64) = MPFRFloat(BigInt(x)) +end +MPFRFloat(x::Float32) = MPFRFloat(float64(x)) +MPFRFloat(x::Rational) = MPFRFloat(num(x)) / MPFRFloat(den(x)) + +# TODO: fix the precision support here +convert{N}(::Type{MPFRFloat{N}}, x::Rational) = MPFRFloat(x) # to resolve ambiguity +convert{N}(::Type{MPFRFloat{N}}, x::Real) = MPFRFloat(x) +convert(::Type{MPFRFloat}, x::Real) = MPFRFloat(x) +convert{N,T}(::Type{MPFRFloat{N}}, x::MPFRFloat{T}) = MPFRFloat(x) + + +convert(::Type{Int64}, x::MPFRFloat) = integer_valued(x) ? + ccall((:mpfr_get_si,:libmpfr), Int64, (Ptr{Void}, Int32), x.mpfr, ROUNDING_MODE[end]) : + throw(InexactError()) +convert(::Type{Int32}, x::MPFRFloat) = int32(convert(Int64, x)) +convert(::Type{Uint64}, x::MPFRFloat) = integer_valued(x) ? + ccall((:mpfr_get_ui,:libmpfr), Uint64, (Ptr{Void}, Int32), x.mpfr, ROUNDING_MODE[end]) : + throw(InexactError()) +function convert(::Type{BigInt}, x::MPFRFloat) + if integer_valued(x) + z = BigInt() + ccall((:mpfr_get_z,:libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpz, x.mpfr, ROUNDING_MODE[end]) + return z + else + throw(InexactError()) + end +end +convert(::Type{Uint32}, x::MPFRFloat) = uint32(convert(Int64, x)) +convert(::Type{Float64}, x::MPFRFloat) = ccall((:mpfr_get_d,:libmpfr), Float64, (Ptr{Void},), x.mpfr) +convert(::Type{Float32}, x::MPFRFloat) = ccall((:mpfr_get_flt,:libmpfr), Float32, (Ptr{Void},), x.mpfr) + +# If two different precisions given, promote to the default +promote_rule{T,S}(::Type{MPFRFloat{T}}, ::Type{MPFRFloat{S}}) = + MPFRFloat{DEFAULT_PRECISION[end]} + +promote_rule{T<:Real,N}(::Type{MPFRFloat{N}}, ::Type{T}) = MPFRFloat{N} +promote_rule{T<:Real}(::Type{MPFRFloat}, ::Type{T}) = MPFRFloat + + +# TODO: Decide if overwriting the default BigFloat rule is good +#promote_rule{T<:FloatingPoint}(::Type{BigInt},::Type{T}) = MPFRFloat{DEFAULT_PRECISION[end]} +#promote_rule{T<:FloatingPoint}(::Type{BigFloat},::Type{T}) = MPFRFloat{DEFAULT_PRECISION[end]} + +# Basic operations + +for (fJ, fC) in ((:+,:add), (:-,:sub), (:*,:mul), (:/,:div), (:^, :pow)) + @eval begin + function ($fJ)(x::MPFRFloat, y::MPFRFloat) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall(($(string(:mpfr_,fC)),:libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, y.mpfr, ROUNDING_MODE[end]) + return z + end + end +end + +function -(x::MPFRFloat) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_neg, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + return z +end + +function cmp(x::MPFRFloat, y::MPFRFloat) + ccall((:mpfr_cmp, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}), x.mpfr, y.mpfr) +end + +function sqrt(x::MPFRFloat) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_sqrt, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + if isnan(z) + throw(DomainError()) + end + return z +end + +for f in (:ceil, :floor, :trunc) + @eval begin + function ($f)(x::MPFRFloat) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ptr{Void}, Ptr{Void}), z.mpfr, x.mpfr) + return z + end + end +end + +function ^(x::MPFRFloat, y::Uint) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_pow_ui, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Uint, Int32), z.mpfr, x.mpfr, y, ROUNDING_MODE[end]) + return z +end + +function ^(x::MPFRFloat, y::Int) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_pow_si, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int, Int32), z.mpfr, x.mpfr, y, ROUNDING_MODE[end]) + return z +end + +function ^(x::MPFRFloat, y::BigInt) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_pow_z, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, y.mpz, ROUNDING_MODE[end]) + return z +end + +function exp(x::MPFRFloat) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_exp, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + return z +end + +function exp2(x::MPFRFloat) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_exp2, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + return z +end + +function exp10(x::MPFRFloat) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_exp10, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + return z +end + +function besselj0(x::MPFRFloat) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_j0, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + return z +end + +function besselj1(x::MPFRFloat) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_j1, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + return z +end + +function besselj(nu::Integer, x::MPFRFloat) + n = int64(nu) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_jn, :libmpfr), Int32, (Ptr{Void}, Int64, Ptr{Void}, Int32), z.mpfr, n, x.mpfr, ROUNDING_MODE[end]) + return z +end + +function bessely0(x::MPFRFloat) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_y0, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + return z +end + +function bessely1(x::MPFRFloat) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_y1, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + return z +end + +function bessely(nu::Integer, x::MPFRFloat) + n = int64(nu) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_yn, :libmpfr), Int32, (Ptr{Void}, Int64, Ptr{Void}, Int32), z.mpfr, n, x.mpfr, ROUNDING_MODE[end]) + return z +end + +function factorial(x::MPFRFloat) + if x < 0 || !integer_valued(x) + throw(DomainError()) + end + ui = uint64(x) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_fac_ui, :libmpfr), Int32, (Ptr{Void}, Uint64, Int32), z.mpfr, ui, ROUNDING_MODE[end]) + return z +end + +function log(x::MPFRFloat) + if x < 0 + throw(DomainError()) + end + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_log, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + return z +end + +function log2(x::MPFRFloat) + if x < 0 + throw(DomainError()) + end + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_log2, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + return z +end + +function log10(x::MPFRFloat) + if x < 0 + throw(DomainError()) + end + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_log10, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + return z +end + +function max(x::MPFRFloat, y::MPFRFloat) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_max, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, y.mpfr, ROUNDING_MODE[end]) + return z +end + +function min(x::MPFRFloat, y::MPFRFloat) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_min, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, y.mpfr, ROUNDING_MODE[end]) + return z +end + +function modf(x::MPFRFloat) + if isinf(x) + return (MPFRFloat(NaN), x) + end + zint = MPFRFloat{DEFAULT_PRECISION[end]}() + zfloat = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_modf, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), zint.mpfr, zfloat.mpfr, x.mpfr, ROUNDING_MODE[end]) + return (zfloat, zint) +end + +function rem(x::MPFRFloat, y::MPFRFloat) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_remainder, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, y.mpfr, ROUNDING_MODE[end]) + return z +end + +function sum{T<:MPFRFloat}(arr::AbstractArray{T}) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + n = length(arr) + ptrarr = [pointer(x.mpfr) for x in arr] + ccall((:mpfr_sum, :libmpfr), Int32, + (Ptr{Void}, Ptr{Void}, Uint, Int32), + z.mpfr, ptrarr, n, ROUNDING_MODE[1]) + return z +end + +# Trigonometric functions +# Every NaN is thrown as an error, and it follows somewhat closely +# the Base functions behavior +for f in (:sin,:cos,:tan,:sec,:csc,:cot,:acos,:asin,:atan, + :cosh,:sinh,:tanh,:sech,:csch,:coth,:acosh,:asinh,:atanh) + @eval begin + function ($f)(x::MPFRFloat) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + if isnan(z) + throw(DomainError()) + end + return z + end + end +end + +# Utility functions +==(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_equal_p, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}), x.mpfr, y.mpfr) != 0 +<=(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_lessequal_p, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}), x.mpfr, y.mpfr) != 0 +>=(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_greaterequal_p, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}), x.mpfr, y.mpfr) != 0 +<(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_less_p, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}), x.mpfr, y.mpfr) != 0 +>(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_greater_p, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}), x.mpfr, y.mpfr) != 0 + +function prec(x::MPFRFloat) + return ccall((:mpfr_get_prec, :libmpfr), Int, (Ptr{Void},), x.mpfr) +end + +get_precision() = DEFAULT_PRECISION[end] +function set_precision(x::Int) + if x < 2 + throw(DomainError()) + end + DEFAULT_PRECISION[end] = x +end + +function copysign(x::MPFRFloat, y::MPFRFloat) + z = MPFRFloat{DEFAULT_PRECISION[end]}() + ccall((:mpfr_copysign, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, y.mpfr, ROUNDING_MODE[end]) + return z +end + +function exponent(x::MPFRFloat) + if x == 0 || !isfinite(x) + throw(DomainError()) + end + # The '- 1' is to make it work as Base.exponent + return ccall((:mpfr_get_exp, :libmpfr), Int, (Ptr{Void},), x.mpfr) - 1 +end + +function integer_valued(x::MPFRFloat) + return ccall((:mpfr_integer_p, :libmpfr), Int32, (Ptr{Void},), x.mpfr) != 0 +end + +function iround(x::MPFRFloat) + fits = ccall((:mpfr_fits_slong_p, :libmpfr), Int32, (Ptr{Void}, Int32), x.mpfr, ROUNDING_MODE[end]) + if fits != 0 + return ccall((:mpfr_get_si, :libmpfr), Int64, (Ptr{Void}, Int32), x.mpfr, ROUNDING_MODE[end]) + end + z = BigInt() + ccall((:mpfr_get_z, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpz, x.mpfr, ROUNDING_MODE[end]) + return z +end + +for (f,t) in ((:uint8,:Uint8), (:uint16,:Uint16), (:uint32,:Uint32), + (:int64,:Int64), (:uint64,:Uint64), + # requires int128/uint128(::Type{BigInt}) support + # (:int128,:Int128), (:uint128,:Uint128), + (:unsigned,:Uint), (:uint,:Uint)) + @eval iround(::Type{$t}, x::MPFRFloat) = ($f)(iround(x)) +end + +isfinite(x::MPFRFloat) = !isinf(x) +function isinf(x::MPFRFloat) + return ccall((:mpfr_inf_p, :libmpfr), Int32, (Ptr{Void},), x.mpfr) != 0 +end + +function isnan(x::MPFRFloat) + return ccall((:mpfr_nan_p, :libmpfr), Int32, (Ptr{Void},), x.mpfr) != 0 +end + +function nextfloat(x::MPFRFloat) + z = MPFRFloat(x) + ccall((:mpfr_nextabove, :libmpfr), Int32, (Ptr{Void},), z.mpfr) != 0 + return z +end + +function prevfloat(x::MPFRFloat) + z = MPFRFloat(x) + ccall((:mpfr_nextbelow, :libmpfr), Int32, (Ptr{Void},), z.mpfr) != 0 + return z +end + +function with_precision(f::Function, precision::Integer) + old_precision = get_precision() + set_precision(precision) + ret = f() + set_precision(old_precision) + return ret +end + +function round(x::MPFRFloat, prec::Int) + if prec < 1 + throw(DomainError()) + end + prec = int(ceil(log2(10^prec))) + z = MPFRFloat(x) + ccall((:mpfr_prec_round, :libmpfr), Int32, (Ptr{Void}, Int, Int32), z.mpfr, prec, ROUNDING_MODE[end]) + return z +end + +function string(x::MPFRFloat) + lng = 128 + for i = 1:2 + z = Array(Uint8, lng) + lng = ccall((:mpfr_snprintf,:libmpfr), Int32, (Ptr{Uint8}, Uint, Ptr{Uint8}, Ptr{Void}...), z, lng, "%.Re", x.mpfr) + if lng < 128 || i == 2 + return bytestring(convert(Ptr{Uint8}, z[1:lng])) + end + end +end + +show(io::IO, b::MPFRFloat) = print(io, string(b) * " with $(prec(b)) bits of precision") +showcompact(io::IO, b::MPFRFloat) = print(io, string(b)) + +end #module diff --git a/base/sysimg.jl b/base/sysimg.jl index 5c904b2f79488..6cc7bdf404687 100644 --- a/base/sysimg.jl +++ b/base/sysimg.jl @@ -173,6 +173,12 @@ importall .DSP include("gmp.jl") importall .GMP +# MPFR and MPC +include("mpfr.jl") +importall .MPFR +include("mpc.jl") +importall .MPC + # deprecated functions include("deprecated.jl") diff --git a/test/mpc.jl b/test/mpc.jl new file mode 100644 index 0000000000000..b3355f6bde894 --- /dev/null +++ b/test/mpc.jl @@ -0,0 +1,65 @@ +# real constructors +x = MPCComplex{53,53}() +x = MPCComplex(12) +y = MPCComplex(x) +@test x == y +y = MPCComplex(0xc) +@test x == y +y = MPCComplex(12.) +@test x == y +y = MPCComplex(BigInt(12)) +@test x == y +y = MPCComplex(BigFloat(12)) +@test x == y +y = MPCComplex(MPFRFloat(12)) +@test x == y +y = MPCComplex("12") +@test x == y +y = MPCComplex(float32(12.)) +@test x == y +y = MPCComplex(12//1) +@test x == y + +# complex constructors +x = MPCComplex(12, 42) +y = MPCComplex(x) +@test x == y +y = MPCComplex(0xc, 0x2a) +@test x == y +y = MPCComplex(12., 42.) +@test x == y +y = MPCComplex(BigInt(12), BigInt(42)) +@test x == y +y = MPCComplex(BigFloat(12), BigFloat(42)) +@test x == y +y = MPCComplex(MPFRFloat(12), MPFRFloat(42)) +@test x == y +y = MPCComplex("(12 42)") +@test x == y +y = MPCComplex(float32(12.), float32(42)) +@test x == y +y = MPCComplex(12//1, 42//1) +@test x == y +y = MPCComplex(12 + 42im) +@test x == y + +# real/imag +x = MPCComplex(12, 42) +y = MPFRFloat(12) +z = MPFRFloat(42) +@test real(x) == y +@test imag(x) == z +y = MPCComplex(x) +@test real(x) == real(y) +@test imag(x) == imag(y) + +# + +x = MPCComplex(12,42) +@test (x + x) == MPCComplex(24, 84) +@test (x + 2) == MPCComplex(14, 42) +@test (x + (2+ 1im)) == MPCComplex(14, 43) +@test (x + 2 + 1im) == MPCComplex(14, 43) + +# integer_valued +@test !integer_valued(MPCComplex(2,3)) +@test integer_valued(MPCComplex(2)) diff --git a/test/mpfr.jl b/test/mpfr.jl new file mode 100644 index 0000000000000..03144d840bc66 --- /dev/null +++ b/test/mpfr.jl @@ -0,0 +1,306 @@ +# constructors +x = MPFRFloat{53}() +x = MPFRFloat(12) +y = MPFRFloat(x) +@test x == y +y = MPFRFloat(0xc) +@test x == y +y = MPFRFloat(12.) +@test x == y +y = MPFRFloat(BigInt(12)) +@test x == y +y = MPFRFloat(BigFloat(12)) +@test x == y +y = MPFRFloat("12") +@test x == y +y = MPFRFloat(float32(12.)) +@test x == y +y = MPFRFloat(12//1) +@test x == y + +# + +x = MPFRFloat(12) +y = MPFRFloat(30) +@test x + y == MPFRFloat(42) + +# - +x = MPFRFloat(12) +y = MPFRFloat(-30) +@test x - y == MPFRFloat(42) + +# * +x = MPFRFloat(6) +y = MPFRFloat(9) +@test x * y != MPFRFloat(42) +@test x * y == MPFRFloat(54) + +# / +x = MPFRFloat(9) +y = MPFRFloat(6) +@test x / y == MPFRFloat(9/6) + +# < / > / <= / >= +x = MPFRFloat(12) +y = MPFRFloat(42) +z = MPFRFloat(30) +@test y > x +@test y >= x +@test y > z +@test y >= z +@test x < y +@test x <= y +@test z < y +@test z <= y +@test y - x >= z +@test y - x <= z +@test !(x >= z) +@test !(y <= z) + +# ^ +x = MPFRFloat(12) +y = MPFRFloat(4) +@test x^y == MPFRFloat(20736) + +# ceil +x = MPFRFloat(12.042) +@test MPFRFloat(13) == ceil(x) + +# copysign +x = MPFRFloat(1) +y = MPFRFloat(-1) +@test copysign(x, y) == y +@test copysign(y, x) == x + +# isfinite / isinf +x = MPFRFloat(Inf) +y = MPFRFloat(1) +@test isinf(x) == true +@test isinf(y) == false +@test isfinite(x) == false +@test isinf(x) == true + +# isnan +x = MPFRFloat(NaN) +y = MPFRFloat(1) +@test isnan(x) == true +@test isnan(y) == false + +# convert to +@test convert(MPFRFloat{53}, 1//2) == MPFRFloat("0.5") +@test convert(MPFRFloat{53}, 0.5) == MPFRFloat("0.5") +@test convert(MPFRFloat{53}, 40) == MPFRFloat("40") +@test convert(MPFRFloat{53}, float32(0.5)) == MPFRFloat("0.5") + +# convert from +@test convert(Float64, MPFRFloat(0.5)) == 0.5 +@test convert(Float32, MPFRFloat(0.5)) == float32(0.5) + +# exponent +x = MPFRFloat(0) +@test_fails exponent(x) +x = MPFRFloat(Inf) +@test_fails exponent(x) +x = MPFRFloat(15.674) +@test exponent(x) == exponent(15.674) + +# sqrt DomainError +@test_fails sqrt(MPFRFloat(-1)) + +# precision +old_precision = get_precision() +x = MPFRFloat(0) +@test prec(x) == old_precision +set_precision(256) +x = MPFRFloat(0) +@test prec(x) == 256 +set_precision(old_precision) +z = with_precision(240) do + z = x + 20 + return z +end +@test float(z) == 20. +@test prec(z) == 240 +x = MPFRFloat(12) +@test prec(x) == old_precision +@test_fails set_precision(1) + +# integer_valued +@test integer_valued(MPFRFloat(12)) +@test !integer_valued(MPFRFloat(12.12)) + +# nextfloat / prevfloat +with_precision(53) do + x = MPFRFloat(12.12) + @test MPFRFloat(nextfloat(12.12)) == nextfloat(x) + @test MPFRFloat(prevfloat(12.12)) == prevfloat(x) +end +@test isnan(nextfloat(MPFRFloat(NaN))) +@test isnan(prevfloat(MPFRFloat(NaN))) + +# comparisons +x = MPFRFloat(1) +y = MPFRFloat(-1) +z = MPFRFloat(NaN) +ipl = MPFRFloat(Inf) +imi = MPFRFloat(-Inf) +@test x > y +@test x >= y +@test x >= x +@test y < x +@test y <= x +@test y <= y +@test x < ipl +@test x <= ipl +@test x > imi +@test x >= imi +@test imi == imi +@test ipl == ipl +@test imi < ipl +@test z != z +@test !(z == z) +@test !(z <= z) +@test !(z < z) +@test !(z >= z) +@test !(z > z) + +# modf +x = MPFRFloat(12) +y = MPFRFloat(0.5) +@test modf(x+y) == (y, x) +x = MPFRFloat(NaN) +@test map(isnan, modf(x)) == (true, true) +x = MPFRFloat(Inf) +y = modf(x) +@test (isnan(y[1]), isinf(y[2])) == (true, true) + +# rem +with_precision(53) do + x = MPFRFloat(2) + y = MPFRFloat(1.67) + @test rem(x,y) == rem(2, 1.67) + y = MPFRFloat(NaN) + @test isnan(rem(x,y)) + @test isnan(rem(y,x)) + y = MPFRFloat(Inf) + @test rem(x,y) == x + @test isnan(rem(y,x)) +end + +# min/max +x = MPFRFloat(4) +y = MPFRFloat(2) +@test max(x,y) == x +@test min(x,y) == y +y = MPFRFloat(NaN) +@test max(x,y) == x +@test min(x,y) == x +@test isnan(max(y,y)) +@test isnan(min(y,y)) + +# sum +x = MPFRFloat(1) +y = MPFRFloat(2) +z = MPFRFloat(3) +w = MPFRFloat(4) +@test sum([x,y,z,w]) == MPFRFloat(10) +big_array = ones(MPFRFloat, 100) +@test sum(big_array) == MPFRFloat(100) + +# promotion +# the array converts everyone to the DEFAULT_PRECISION! +x = MPFRFloat(12) +y = with_precision(60) do + MPFRFloat(42) +end +@test [x,y] == [MPFRFloat(12), MPFRFloat(42)] + +# log / log2 / log10 +x = MPFRFloat(42) +@test log(x) == log(42) +@test isinf(log(MPFRFloat(0))) +@test_fails log(MPFRFloat(-1)) +@test log2(x) == log2(42) +@test isinf(log2(MPFRFloat(0))) +@test_fails log2(MPFRFloat(-1)) +@test log10(x) == log10(42) +@test isinf(log10(MPFRFloat(0))) +@test_fails log10(MPFRFloat(-1)) + +# exp / exp2 / exp10 +x = MPFRFloat(10) +@test exp(x) == exp(10) +@test exp2(x) == 1024 +@test exp10(x) == 10000000000 + +# convert to integer types +x = MPFRFloat(12.1) +y = MPFRFloat(42) +@test_fails convert(Int32, x) +@test_fails convert(Int64, x) +@test_fails convert(BigInt, x) +@test_fails convert(Uint32, x) +@test_fails convert(Uint32, x) +@test convert(Int32, y) == 42 +@test convert(Int64, y) == 42 +@test convert(BigInt, y) == 42 +@test convert(Uint32, y) == 42 +@test convert(Uint32, y) == 42 + +# iround +x = MPFRFloat(42.42) +y = with_precision(256) do + MPFRFloat("9223372036854775809.2324") +end +z = BigInt("9223372036854775809") +@test iround(x) == 42 +@test iround(y) == z +@test typeof(iround(Uint8, x)) == Uint8 && iround(Uint8, x) == 0x2a +@test typeof(iround(Uint16, x)) == Uint16 && iround(Uint16, x) == 0x2a +@test typeof(iround(Uint32, x)) == Uint32 && iround(Uint32, x) == 0x2a +@test typeof(iround(Uint64, x)) == Uint64 && iround(Uint64, x) == 0x2a +@test typeof(iround(Int64, x)) == Int64 && iround(Int64, x) == 42 +@test typeof(iround(Int, x)) == Int && iround(Int, x) == 42 +@test typeof(iround(Uint, x)) == Uint && iround(Uint, x) == 0x2a + +# factorial +with_precision(256) do + x = MPFRFloat(42) + @test factorial(x) == factorial(BigInt(42)) + x = MPFRFloat(10) + @test factorial(x) == factorial(10) + @test_fails factorial(MPFRFloat(-1)) + @test_fails factorial(MPFRFloat(331.3)) +end + +# bessel functions +@test_approx_eq besselj(4, MPFRFloat(2)) besselj(4, 2.) +@test_approx_eq besselj0(MPFRFloat(2)) besselj0(2.) +@test_approx_eq besselj1(MPFRFloat(2)) besselj1(2.) +@test_approx_eq bessely(4, MPFRFloat(2)) bessely(4, 2.) +@test_approx_eq bessely0(MPFRFloat(2)) bessely0(2.) +@test_approx_eq bessely1(MPFRFloat(2)) bessely1(2.) + +# trigonometric functions +for f in (:sin,:cos,:tan,:sec,:csc,:cot,:acos,:asin,:atan, + :cosh,:sinh,:tanh,:sech,:csch,:coth,:asinh), + j in (-1., -0.5, -0.25, .25, .5, 1.) + @eval begin + @test_approx_eq ($f)(MPFRFloat($j)) ($f)($j) + end +end +for f in (:acos,:asin,:acosh,:atanh), + j in (-2, -1.5) + @eval begin + @test_fails ($f)(MPFRFloat($j)) + end +end +for f in (:sin,:cos,:tan,:sec,:csc,:cot,:cosh,:sinh,:tanh, + :sech,:csch,:coth,:acosh,:asinh), + j in (1., 1.5, 1.9) + @eval begin + @test_approx_eq ($f)(MPFRFloat($j)) ($f)($j) + end +end +for j in (.25, .5) + @test_approx_eq atanh(MPFRFloat(j)) atanh(j) +end diff --git a/test/runtests.jl b/test/runtests.jl index 3e9f27f688eba..96b0c7d4cb307 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,7 +4,7 @@ testnames = ["core", "keywordargs", "numbers", "strings", "unicode", "random", "math", "functional", "bigint", "sorting", "statistics", "spawn", "parallel", "priorityqueue", "arpack", "bigfloat", "file", "perf", "suitesparse", "version", - "pollfd"] + "pollfd", "mpfr", "mpc"] # Disabled: "complex" From f48a16a6786c8226d22e038621eef76ef1881c58 Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Thu, 11 Apr 2013 17:42:31 -0300 Subject: [PATCH 05/31] Change BigInt to use a precise mpz_struct As discussed in #2814. --- base/bigfloat.jl | 2 +- base/bigint.jl | 51 ++++++++++++++++++++++++------------------------ base/gmp.jl | 6 ++++++ base/mpc.jl | 6 +++--- base/mpfr.jl | 8 ++++---- 5 files changed, 39 insertions(+), 34 deletions(-) diff --git a/base/bigfloat.jl b/base/bigfloat.jl index d32c693626dd7..747a259ae4ec6 100644 --- a/base/bigfloat.jl +++ b/base/bigfloat.jl @@ -44,7 +44,7 @@ end function BigFloat(x::BigInt) z = BigFloat() - ccall((:__gmpf_set_z, :libgmp), Void, (Ptr{Void}, Ptr{Void}), z.mpf, x.mpz) + ccall((:__gmpf_set_z, :libgmp), Void, (Ptr{Void}, Ptr{mpz_struct}), z.mpf, &(x.mpz)) return z end diff --git a/base/bigint.jl b/base/bigint.jl index 206cb2b809bbe..52d49b8d594a0 100644 --- a/base/bigint.jl +++ b/base/bigint.jl @@ -1,39 +1,38 @@ -BigInt_clear(mpz::Vector{Int32}) = ccall((:__gmpz_clear, :libgmp), Void, (Ptr{Void},), mpz) - -immutable BigInt <: Integer - mpz::Vector{Int32} +type BigInt <: Integer + mpz::mpz_struct function BigInt() - z = Array(Int32, 4) - ccall((:__gmpz_init,:libgmp), Void, (Ptr{Void},), z) + z = mpz_struct(int32(0), int32(0), C_NULL) + ccall((:__gmpz_init,:libgmp), Void, (Ptr{mpz_struct},), &z) b = new(z) finalizer(b.mpz, BigInt_clear) return b end end +BigInt_clear(mpz::mpz_struct) = ccall((:__gmpz_clear, :libgmp), Void, (Ptr{mpz_struct},), &mpz) function BigInt(x::BigInt) z = BigInt() - ccall((:__gmpz_set, :libgmp), Void, (Ptr{Void}, Ptr{Void}), z.mpz, x.mpz) + ccall((:__gmpz_set, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}), &(z.mpz), &(x.mpz)) return z end function BigInt(x::String) z = BigInt() - err = ccall((:__gmpz_set_str, :libgmp), Int32, (Ptr{Void}, Ptr{Uint8}, Int32), z.mpz, bytestring(x), 0) + err = ccall((:__gmpz_set_str, :libgmp), Int32, (Ptr{mpz_struct}, Ptr{Uint8}, Int32), &(z.mpz), bytestring(x), 0) if err != 0; error("Invalid input"); end return z end function BigInt(x::Int) z = BigInt() - ccall((:__gmpz_set_si, :libgmp), Void, (Ptr{Void}, Int), z.mpz, x) + ccall((:__gmpz_set_si, :libgmp), Void, (Ptr{mpz_struct}, Int), &(z.mpz), x) return z end function BigInt(x::Uint) z = BigInt() ccall((:__gmpz_set_ui, :libgmp), Void, - (Ptr{Void}, Uint), z.mpz, x) + (Ptr{mpz_struct}, Uint), &(z.mpz), x) return z end @@ -50,10 +49,10 @@ end convert{T<:Integer}(::Type{BigInt}, x::T) = BigInt(x) convert(::Type{Int}, n::BigInt) = - ccall((:__gmpz_get_si, :libgmp), Int, (Ptr{Void},), n.mpz) + ccall((:__gmpz_get_si, :libgmp), Int, (Ptr{mpz_struct},), &(n.mpz)) convert(::Type{Uint}, n::BigInt) = - ccall((:__gmpz_get_ui, :libgmp), Uint, (Ptr{Void},), n.mpz) + ccall((:__gmpz_get_ui, :libgmp), Uint, (Ptr{mpz_struct},), &(n.mpz)) promote_rule{T<:Integer}(::Type{BigInt}, ::Type{T}) = BigInt @@ -65,7 +64,7 @@ for (fJ, fC) in ((:+, :add), (:-,:sub), (:*, :mul), @eval begin function ($fJ)(x::BigInt, y::BigInt) z = BigInt() - ccall(($(string(:__gmpz_,fC)), :libgmp), Void, (Ptr{Void}, Ptr{Void}, Ptr{Void}), z.mpz, x.mpz, y.mpz) + ccall(($(string(:__gmpz_,fC)), :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}, Ptr{mpz_struct}), &(z.mpz), &(x.mpz), &(y.mpz)) return z end end @@ -76,7 +75,7 @@ for (fJ, fC) in ((:-, :neg), (:~, :com)) @eval begin function ($fJ)(x::BigInt) z = BigInt() - ccall(($(string(:__gmpz_,fC)), :libgmp), Void, (Ptr{Void}, Ptr{Void}), z.mpz, x.mpz) + ccall(($(string(:__gmpz_,fC)), :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}), &(z.mpz), &(x.mpz)) return z end end @@ -84,7 +83,7 @@ end function <<(x::BigInt, c::Uint) z = BigInt() - ccall((:__gmpz_mul_2exp, :libgmp), Void, (Ptr{Void}, Ptr{Void}, Uint), z.mpz, x.mpz, c) + ccall((:__gmpz_mul_2exp, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}, Uint), &(z.mpz), &(x.mpz), c) return z end <<(x::BigInt, c::Int32) = c<0 ? throw(DomainError()) : x<>(x::BigInt, c::Uint) z = BigInt() - ccall((:__gmpz_fdiv_q_2exp, :libgmp), Void, (Ptr{Void}, Ptr{Void}, Uint), z.mpz, x.mpz, c) + ccall((:__gmpz_fdiv_q_2exp, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}, Uint), &(z.mpz), &(x.mpz), c) return z end >>(x::BigInt, c::Int32) = c<0 ? throw(DomainError()) : x>>uint(c) @@ -101,23 +100,23 @@ end function divrem(x::BigInt, y::BigInt) z1 = BigInt() z2 = BigInt() - ccall((:__gmpz_tdiv_qr, :libgmp), Void, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Ptr{Void}), z1.mpz, z2.mpz, x.mpz, y.mpz) + ccall((:__gmpz_tdiv_qr, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}, Ptr{mpz_struct}, Ptr{mpz_struct}), &(z1.mpz), &(z2.mpz), &(x.mpz), &(y.mpz)) z1, z2 end function cmp(x::BigInt, y::BigInt) - ccall((:__gmpz_cmp, :libgmp), Int32, (Ptr{Void}, Ptr{Void}), x.mpz, y.mpz) + ccall((:__gmpz_cmp, :libgmp), Int32, (Ptr{mpz_struct}, Ptr{mpz_struct}), &(x.mpz), &(y.mpz)) end function sqrt(x::BigInt) z = BigInt() - ccall((:__gmpz_sqrt, :libgmp), Void, (Ptr{Void}, Ptr{Void}), z.mpz, x.mpz) + ccall((:__gmpz_sqrt, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}), &(z.mpz), &(x.mpz)) return z end function ^(x::BigInt, y::Uint) z = BigInt() - ccall((:__gmpz_pow_ui, :libgmp), Void, (Ptr{Void}, Ptr{Void}, Uint), z.mpz, x.mpz, y) + ccall((:__gmpz_pow_ui, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}, Uint), &(z.mpz), &(x.mpz), y) return z end @@ -139,8 +138,8 @@ function gcdx(a::BigInt, b::BigInt) s = BigInt() t = BigInt() ccall((:__gmpz_gcdext, :libgmp), Void, - (Ptr{Void}, Ptr{Void}, Ptr{Void}, Ptr{Void}, Ptr{Void}), - g, s, t, a.mpz, b.mpz) + (Ptr{mpz_struct}, Ptr{mpz_struct}, Ptr{mpz_struct}, Ptr{mpz_struct}, Ptr{mpz_struct}), + &(g.mpz), &(s.mpz), &(t.mpz), &(a.mpz), &(b.mpz)) BigInt(g), BigInt(s), BigInt(t) end @@ -152,14 +151,14 @@ function factorial(bn::BigInt) end z = BigInt() ccall((:__gmpz_fac_ui, :libgmp), Void, - (Ptr{Void}, Uint), z.mpz, n) + (Ptr{mpz_struct}, Uint), &(z.mpz), n) return z end function binomial(n::BigInt, k::Uint) z = BigInt() ccall((:__gmpz_bin_ui, :libgmp), Void, - (Ptr{Void}, Ptr{Void}, Uint), z.mpz, n.mpz, k) + (Ptr{mpz_struct}, Ptr{mpz_struct}, Uint), &(z.mpz), &(n.mpz), k) return z end binomial(n::BigInt, k::Integer) = k<0 ? throw(DomainError()) : binomial(n, uint(k)) @@ -173,7 +172,7 @@ binomial(n::BigInt, k::Integer) = k<0 ? throw(DomainError()) : binomial(n, uint( function string(x::BigInt) lng = ndigits(x) + 2 z = Array(Uint8, lng) - lng = ccall((:__gmp_snprintf,:libgmp), Int32, (Ptr{Uint8}, Uint, Ptr{Uint8}, Ptr{Void}...), z, lng, "%Zd", x.mpz) + lng = ccall((:__gmp_snprintf,:libgmp), Int32, (Ptr{Uint8}, Uint, Ptr{Uint8}, Ptr{mpz_struct}...), z, lng, "%Zd", &(x.mpz)) return bytestring(convert(Ptr{Uint8}, z[1:lng])) end @@ -181,4 +180,4 @@ function show(io::IO, x::BigInt) print(io, string(x)) end -ndigits(x::BigInt) = ccall((:__gmpz_sizeinbase,:libgmp), Uint, (Ptr{Void}, Int32), x.mpz, 10) +ndigits(x::BigInt) = ccall((:__gmpz_sizeinbase,:libgmp), Uint, (Ptr{mpz_struct}, Int32), &(x.mpz), 10) diff --git a/base/gmp.jl b/base/gmp.jl index f0dae0bc6429b..1321956e34bf8 100644 --- a/base/gmp.jl +++ b/base/gmp.jl @@ -43,6 +43,12 @@ import Base.string, Base.trunc +type mpz_struct + alloc::Cint + size::Cint + d::Ptr{Void} +end + include("bigint.jl") include("bigfloat.jl") diff --git a/base/mpc.jl b/base/mpc.jl index c6b05f2a5de02..694778f3713b4 100644 --- a/base/mpc.jl +++ b/base/mpc.jl @@ -54,7 +54,7 @@ end function MPCComplex(x::BigInt) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_z, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpz, ROUNDING_MODE) + ccall((:mpc_set_z, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpc, &(x.mpz), ROUNDING_MODE) return z end @@ -127,7 +127,7 @@ end function MPCComplex(x::BigInt, y::BigInt) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_z_z, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpz, y.mpz, ROUNDING_MODE) + ccall((:mpc_set_z_z, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpc, &(x.mpz), &(y.mpz), ROUNDING_MODE) return z end @@ -201,7 +201,7 @@ end function ^(x::MPCComplex, y::BigInt) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_pow_z, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpc, y.mpz, ROUNDING_MODE) + ccall((:mpc_pow_z, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpc, &(y.mpz), ROUNDING_MODE) return z end diff --git a/base/mpfr.jl b/base/mpfr.jl index fdf3735f00f8d..c3675d896ae0c 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -59,7 +59,7 @@ end function MPFRFloat(x::BigInt) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_set_z, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpz, ROUNDING_MODE[end]) + ccall((:mpfr_set_z, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, &(x.mpz), ROUNDING_MODE[end]) return z end @@ -105,7 +105,7 @@ convert(::Type{Uint64}, x::MPFRFloat) = integer_valued(x) ? function convert(::Type{BigInt}, x::MPFRFloat) if integer_valued(x) z = BigInt() - ccall((:mpfr_get_z,:libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpz, x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_get_z,:libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), &(z.mpz), x.mpfr, ROUNDING_MODE[end]) return z else throw(InexactError()) @@ -182,7 +182,7 @@ end function ^(x::MPFRFloat, y::BigInt) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_pow_z, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, y.mpz, ROUNDING_MODE[end]) + ccall((:mpfr_pow_z, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, &(y.mpz), ROUNDING_MODE[end]) return z end @@ -377,7 +377,7 @@ function iround(x::MPFRFloat) return ccall((:mpfr_get_si, :libmpfr), Int64, (Ptr{Void}, Int32), x.mpfr, ROUNDING_MODE[end]) end z = BigInt() - ccall((:mpfr_get_z, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpz, x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_get_z, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), &(z.mpz), x.mpfr, ROUNDING_MODE[end]) return z end From 5142d1d1ac51a4c0ac5230184200879423c9d350 Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Thu, 11 Apr 2013 17:45:32 -0300 Subject: [PATCH 06/31] Install libmpfr-dev and libmpc-dev packages explicitly --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1f83af06ae8da..66fe42985df6c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ before_install: - sudo apt-get install zlib1g-dev - sudo add-apt-repository ppa:staticfloat/julia-deps -y - sudo apt-get update -qq -y - - sudo apt-get install patchelf gfortran llvm-3.2-dev libsuitesparse-dev libncurses5-dev libopenblas-dev liblapack-dev libarpack2-dev libfftw3-dev libgmp-dev libpcre3-dev libunwind7-dev libreadline-dev libdouble-conversion-dev libopenlibm-dev librmath-dev libuv-julia-dev -y + - sudo apt-get install patchelf gfortran llvm-3.2-dev libsuitesparse-dev libncurses5-dev libopenblas-dev liblapack-dev libarpack2-dev libfftw3-dev libgmp-dev libpcre3-dev libunwind7-dev libreadline-dev libdouble-conversion-dev libopenlibm-dev librmath-dev libuv-julia-dev libmpfr-dev libmpc-dev -y script: - make $BUILDOPTS PREFIX=/tmp/julia install - cd .. && mv julia julia2 From f88a6400532a892984d2721f437bcd93b3de067c Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Thu, 11 Apr 2013 18:23:21 -0300 Subject: [PATCH 07/31] Update MPFRFloat to use a precise sized mpfr_struct As discussed in #2814. The function `sum` is disabled currently (so the default one is used as a fallback), as it needs direct pointer access to each of the members of the array. --- base/mpc.jl | 8 +-- base/mpfr.jl | 143 +++++++++++++++++++++++++++------------------------ 2 files changed, 79 insertions(+), 72 deletions(-) diff --git a/base/mpc.jl b/base/mpc.jl index 694778f3713b4..b5a93f274fd37 100644 --- a/base/mpc.jl +++ b/base/mpc.jl @@ -66,7 +66,7 @@ end function MPCComplex(x::MPFRFloat) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_fr, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpfr, ROUNDING_MODE) + ccall((:mpc_set_fr, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpc, &(x.mpfr), ROUNDING_MODE) return z end @@ -139,7 +139,7 @@ end function MPCComplex(x::MPFRFloat, y::MPFRFloat) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_fr_fr, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpfr, y.mpfr, ROUNDING_MODE) + ccall((:mpc_set_fr_fr, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpc, &(x.mpfr), &(y.mpfr), ROUNDING_MODE) return z end @@ -245,13 +245,13 @@ end function imag{N,P}(x::MPCComplex{N,P}) z = MPFRFloat{N}() - ccall((:mpc_imag, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpc, ROUNDING_MODE) + ccall((:mpc_imag, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), &(z.mpfr), x.mpc, ROUNDING_MODE) return z end function real{N,P}(x::MPCComplex{N,P}) z = MPFRFloat{N}() - ccall((:mpc_real, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpc, ROUNDING_MODE) + ccall((:mpc_real, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), &(z.mpfr), x.mpc, ROUNDING_MODE) return z end diff --git a/base/mpfr.jl b/base/mpfr.jl index c3675d896ae0c..34b19ce6739cc 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -25,25 +25,32 @@ const DEFAULT_PRECISION = [53, 53] # Basic type and initialization definitions -immutable MPFRFloat{N} <: FloatingPoint - mpfr::Vector{Int32} +type mpfr_struct + prec::Clong + sign::Cint + exp::Clong + d::Ptr{Void} +end + +type MPFRFloat{N} <: FloatingPoint + mpfr::mpfr_struct function MPFRFloat() if N < 2 error("Invalid precision") end - z = Array(Int32, 5) - ccall((:mpfr_init2,:libmpfr), Void, (Ptr{Void}, Int), z, N) + z = mpfr_struct(convert(Clong, 0), convert(Cint, 0), convert(Clong, 0), C_NULL) + ccall((:mpfr_init2,:libmpfr), Void, (Ptr{mpfr_struct}, Int), &z, N) b = new(z) finalizer(b.mpfr, MPFR_clear) return b end end -MPFR_clear(mpfr::Vector{Int32}) = ccall((:mpfr_clear, :libmpfr), Void, (Ptr{Void},), mpfr) +MPFR_clear(mpfr::Vector{Int32}) = ccall((:mpfr_clear, :libmpfr), Void, (Ptr{mpfr_struct},), &mpfr) function MPFRFloat(x::MPFRFloat) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_set, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_set, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) return z end @@ -51,7 +58,7 @@ for (fJ, fC) in ((:si,:Int), (:ui,:Uint), (:d,:Float64)) @eval begin function MPFRFloat(x::($fC)) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall(($(string(:mpfr_set_,fJ)), :libmpfr), Int32, (Ptr{Void}, ($fC), Int32), z.mpfr, x, ROUNDING_MODE[end]) + ccall(($(string(:mpfr_set_,fJ)), :libmpfr), Int32, (Ptr{mpfr_struct}, ($fC), Int32), &(z.mpfr), x, ROUNDING_MODE[end]) return z end end @@ -59,19 +66,19 @@ end function MPFRFloat(x::BigInt) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_set_z, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, &(x.mpz), ROUNDING_MODE[end]) + ccall((:mpfr_set_z, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{Void}, Int32), &(z.mpfr), &(x.mpz), ROUNDING_MODE[end]) return z end function MPFRFloat(x::BigFloat) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_set_f, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpf, ROUNDING_MODE[end]) + ccall((:mpfr_set_f, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{Void}, Int32), &(z.mpfr), x.mpf, ROUNDING_MODE[end]) return z end function MPFRFloat(x::String, base::Int) z = MPFRFloat{DEFAULT_PRECISION[end]}() - err = ccall((:mpfr_set_str, :libmpfr), Int32, (Ptr{Void}, Ptr{Uint8}, Int32, Int32), z.mpfr, x, base, ROUNDING_MODE[end]) + err = ccall((:mpfr_set_str, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{Uint8}, Int32, Int32), &(z.mpfr), x, base, ROUNDING_MODE[end]) if err != 0; error("Invalid input"); end return z end @@ -96,24 +103,24 @@ convert{N,T}(::Type{MPFRFloat{N}}, x::MPFRFloat{T}) = MPFRFloat(x) convert(::Type{Int64}, x::MPFRFloat) = integer_valued(x) ? - ccall((:mpfr_get_si,:libmpfr), Int64, (Ptr{Void}, Int32), x.mpfr, ROUNDING_MODE[end]) : + ccall((:mpfr_get_si,:libmpfr), Int64, (Ptr{mpfr_struct}, Int32), &(x.mpfr), ROUNDING_MODE[end]) : throw(InexactError()) convert(::Type{Int32}, x::MPFRFloat) = int32(convert(Int64, x)) convert(::Type{Uint64}, x::MPFRFloat) = integer_valued(x) ? - ccall((:mpfr_get_ui,:libmpfr), Uint64, (Ptr{Void}, Int32), x.mpfr, ROUNDING_MODE[end]) : + ccall((:mpfr_get_ui,:libmpfr), Uint64, (Ptr{mpfr_struct}, Int32), &(x.mpfr), ROUNDING_MODE[end]) : throw(InexactError()) function convert(::Type{BigInt}, x::MPFRFloat) if integer_valued(x) z = BigInt() - ccall((:mpfr_get_z,:libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), &(z.mpz), x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_get_z,:libmpfr), Int32, (Ptr{Void}, Ptr{mpfr_struct}, Int32), &(z.mpz), &(x.mpfr), ROUNDING_MODE[end]) return z else throw(InexactError()) end end convert(::Type{Uint32}, x::MPFRFloat) = uint32(convert(Int64, x)) -convert(::Type{Float64}, x::MPFRFloat) = ccall((:mpfr_get_d,:libmpfr), Float64, (Ptr{Void},), x.mpfr) -convert(::Type{Float32}, x::MPFRFloat) = ccall((:mpfr_get_flt,:libmpfr), Float32, (Ptr{Void},), x.mpfr) +convert(::Type{Float64}, x::MPFRFloat) = ccall((:mpfr_get_d,:libmpfr), Float64, (Ptr{mpfr_struct},), &(x.mpfr)) +convert(::Type{Float32}, x::MPFRFloat) = ccall((:mpfr_get_flt,:libmpfr), Float32, (Ptr{mpfr_struct},), &(x.mpfr)) # If two different precisions given, promote to the default promote_rule{T,S}(::Type{MPFRFloat{T}}, ::Type{MPFRFloat{S}}) = @@ -133,7 +140,7 @@ for (fJ, fC) in ((:+,:add), (:-,:sub), (:*,:mul), (:/,:div), (:^, :pow)) @eval begin function ($fJ)(x::MPFRFloat, y::MPFRFloat) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall(($(string(:mpfr_,fC)),:libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, y.mpfr, ROUNDING_MODE[end]) + ccall(($(string(:mpfr_,fC)),:libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), &(y.mpfr), ROUNDING_MODE[end]) return z end end @@ -141,17 +148,17 @@ end function -(x::MPFRFloat) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_neg, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_neg, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) return z end function cmp(x::MPFRFloat, y::MPFRFloat) - ccall((:mpfr_cmp, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}), x.mpfr, y.mpfr) + ccall((:mpfr_cmp, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}), &(x.mpfr), &(y.mpfr)) end function sqrt(x::MPFRFloat) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_sqrt, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_sqrt, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) if isnan(z) throw(DomainError()) end @@ -162,7 +169,7 @@ for f in (:ceil, :floor, :trunc) @eval begin function ($f)(x::MPFRFloat) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ptr{Void}, Ptr{Void}), z.mpfr, x.mpfr) + ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}), &(z.mpfr), &(x.mpfr)) return z end end @@ -170,75 +177,75 @@ end function ^(x::MPFRFloat, y::Uint) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_pow_ui, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Uint, Int32), z.mpfr, x.mpfr, y, ROUNDING_MODE[end]) + ccall((:mpfr_pow_ui, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Uint, Int32), &(z.mpfr), &(x.mpfr), y, ROUNDING_MODE[end]) return z end function ^(x::MPFRFloat, y::Int) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_pow_si, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int, Int32), z.mpfr, x.mpfr, y, ROUNDING_MODE[end]) + ccall((:mpfr_pow_si, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int, Int32), &(z.mpfr), &(x.mpfr), y, ROUNDING_MODE[end]) return z end function ^(x::MPFRFloat, y::BigInt) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_pow_z, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, &(y.mpz), ROUNDING_MODE[end]) + ccall((:mpfr_pow_z, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Ptr{Void}, Int32), &(z.mpfr), &(x.mpfr), &(y.mpz), ROUNDING_MODE[end]) return z end function exp(x::MPFRFloat) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_exp, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_exp, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) return z end function exp2(x::MPFRFloat) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_exp2, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_exp2, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) return z end function exp10(x::MPFRFloat) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_exp10, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_exp10, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) return z end function besselj0(x::MPFRFloat) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_j0, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_j0, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) return z end function besselj1(x::MPFRFloat) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_j1, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_j1, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) return z end function besselj(nu::Integer, x::MPFRFloat) n = int64(nu) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_jn, :libmpfr), Int32, (Ptr{Void}, Int64, Ptr{Void}, Int32), z.mpfr, n, x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_jn, :libmpfr), Int32, (Ptr{mpfr_struct}, Int64, Ptr{mpfr_struct}, Int32), &(z.mpfr), n, &(x.mpfr), ROUNDING_MODE[end]) return z end function bessely0(x::MPFRFloat) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_y0, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_y0, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) return z end function bessely1(x::MPFRFloat) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_y1, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_y1, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) return z end function bessely(nu::Integer, x::MPFRFloat) n = int64(nu) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_yn, :libmpfr), Int32, (Ptr{Void}, Int64, Ptr{Void}, Int32), z.mpfr, n, x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_yn, :libmpfr), Int32, (Ptr{mpfr_struct}, Int64, Ptr{mpfr_struct}, Int32), &(z.mpfr), n, &(x.mpfr), ROUNDING_MODE[end]) return z end @@ -248,7 +255,7 @@ function factorial(x::MPFRFloat) end ui = uint64(x) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_fac_ui, :libmpfr), Int32, (Ptr{Void}, Uint64, Int32), z.mpfr, ui, ROUNDING_MODE[end]) + ccall((:mpfr_fac_ui, :libmpfr), Int32, (Ptr{mpfr_struct}, Uint64, Int32), &(z.mpfr), ui, ROUNDING_MODE[end]) return z end @@ -257,7 +264,7 @@ function log(x::MPFRFloat) throw(DomainError()) end z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_log, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_log, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) return z end @@ -266,7 +273,7 @@ function log2(x::MPFRFloat) throw(DomainError()) end z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_log2, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_log2, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) return z end @@ -275,19 +282,19 @@ function log10(x::MPFRFloat) throw(DomainError()) end z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_log10, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_log10, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) return z end function max(x::MPFRFloat, y::MPFRFloat) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_max, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, y.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_max, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), &(y.mpfr), ROUNDING_MODE[end]) return z end function min(x::MPFRFloat, y::MPFRFloat) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_min, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, y.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_min, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), &(y.mpfr), ROUNDING_MODE[end]) return z end @@ -297,25 +304,25 @@ function modf(x::MPFRFloat) end zint = MPFRFloat{DEFAULT_PRECISION[end]}() zfloat = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_modf, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), zint.mpfr, zfloat.mpfr, x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_modf, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(zint.mpfr), &(zfloat.mpfr), &(x.mpfr), ROUNDING_MODE[end]) return (zfloat, zint) end function rem(x::MPFRFloat, y::MPFRFloat) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_remainder, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, y.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_remainder, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), &(y.mpfr), ROUNDING_MODE[end]) return z end -function sum{T<:MPFRFloat}(arr::AbstractArray{T}) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - n = length(arr) - ptrarr = [pointer(x.mpfr) for x in arr] - ccall((:mpfr_sum, :libmpfr), Int32, - (Ptr{Void}, Ptr{Void}, Uint, Int32), - z.mpfr, ptrarr, n, ROUNDING_MODE[1]) - return z -end +# function sum{T<:MPFRFloat}(arr::AbstractArray{T}) +# z = MPFRFloat{DEFAULT_PRECISION[end]}() +# n = length(arr) +# ptrarr = [pointer(&(x.mpfr)) for x in arr] +# ccall((:mpfr_sum, :libmpfr), Int32, +# (Ptr{mpfr_struct}, Ptr{Void}, Uint, Int32), +# &(z.mpfr), ptrarr, n, ROUNDING_MODE[1]) +# return z +# end # Trigonometric functions # Every NaN is thrown as an error, and it follows somewhat closely @@ -325,7 +332,7 @@ for f in (:sin,:cos,:tan,:sec,:csc,:cot,:acos,:asin,:atan, @eval begin function ($f)(x::MPFRFloat) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, ROUNDING_MODE[end]) + ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) if isnan(z) throw(DomainError()) end @@ -335,14 +342,14 @@ for f in (:sin,:cos,:tan,:sec,:csc,:cot,:acos,:asin,:atan, end # Utility functions -==(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_equal_p, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}), x.mpfr, y.mpfr) != 0 -<=(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_lessequal_p, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}), x.mpfr, y.mpfr) != 0 ->=(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_greaterequal_p, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}), x.mpfr, y.mpfr) != 0 -<(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_less_p, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}), x.mpfr, y.mpfr) != 0 ->(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_greater_p, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}), x.mpfr, y.mpfr) != 0 +==(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_equal_p, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}), &(x.mpfr), &(y.mpfr)) != 0 +<=(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_lessequal_p, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}), &(x.mpfr), &(y.mpfr)) != 0 +>=(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_greaterequal_p, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}), &(x.mpfr), &(y.mpfr)) != 0 +<(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_less_p, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}), &(x.mpfr), &(y.mpfr)) != 0 +>(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_greater_p, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}), &(x.mpfr), &(y.mpfr)) != 0 function prec(x::MPFRFloat) - return ccall((:mpfr_get_prec, :libmpfr), Int, (Ptr{Void},), x.mpfr) + return ccall((:mpfr_get_prec, :libmpfr), Int, (Ptr{mpfr_struct},), &(x.mpfr)) end get_precision() = DEFAULT_PRECISION[end] @@ -355,7 +362,7 @@ end function copysign(x::MPFRFloat, y::MPFRFloat) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_copysign, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpfr, x.mpfr, y.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_copysign, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), &(y.mpfr), ROUNDING_MODE[end]) return z end @@ -364,20 +371,20 @@ function exponent(x::MPFRFloat) throw(DomainError()) end # The '- 1' is to make it work as Base.exponent - return ccall((:mpfr_get_exp, :libmpfr), Int, (Ptr{Void},), x.mpfr) - 1 + return ccall((:mpfr_get_exp, :libmpfr), Int, (Ptr{mpfr_struct},), &(x.mpfr)) - 1 end function integer_valued(x::MPFRFloat) - return ccall((:mpfr_integer_p, :libmpfr), Int32, (Ptr{Void},), x.mpfr) != 0 + return ccall((:mpfr_integer_p, :libmpfr), Int32, (Ptr{mpfr_struct},), &(x.mpfr)) != 0 end function iround(x::MPFRFloat) - fits = ccall((:mpfr_fits_slong_p, :libmpfr), Int32, (Ptr{Void}, Int32), x.mpfr, ROUNDING_MODE[end]) + fits = ccall((:mpfr_fits_slong_p, :libmpfr), Int32, (Ptr{mpfr_struct}, Int32), &(x.mpfr), ROUNDING_MODE[end]) if fits != 0 - return ccall((:mpfr_get_si, :libmpfr), Int64, (Ptr{Void}, Int32), x.mpfr, ROUNDING_MODE[end]) + return ccall((:mpfr_get_si, :libmpfr), Int64, (Ptr{mpfr_struct}, Int32), &(x.mpfr), ROUNDING_MODE[end]) end z = BigInt() - ccall((:mpfr_get_z, :libmpfr), Int32, (Ptr{Void}, Ptr{Void}, Int32), &(z.mpz), x.mpfr, ROUNDING_MODE[end]) + ccall((:mpfr_get_z, :libmpfr), Int32, (Ptr{Void}, Ptr{mpfr_struct}, Int32), &(z.mpz), &(x.mpfr), ROUNDING_MODE[end]) return z end @@ -391,22 +398,22 @@ end isfinite(x::MPFRFloat) = !isinf(x) function isinf(x::MPFRFloat) - return ccall((:mpfr_inf_p, :libmpfr), Int32, (Ptr{Void},), x.mpfr) != 0 + return ccall((:mpfr_inf_p, :libmpfr), Int32, (Ptr{mpfr_struct},), &(x.mpfr)) != 0 end function isnan(x::MPFRFloat) - return ccall((:mpfr_nan_p, :libmpfr), Int32, (Ptr{Void},), x.mpfr) != 0 + return ccall((:mpfr_nan_p, :libmpfr), Int32, (Ptr{mpfr_struct},), &(x.mpfr)) != 0 end function nextfloat(x::MPFRFloat) z = MPFRFloat(x) - ccall((:mpfr_nextabove, :libmpfr), Int32, (Ptr{Void},), z.mpfr) != 0 + ccall((:mpfr_nextabove, :libmpfr), Int32, (Ptr{mpfr_struct},), &(z.mpfr)) != 0 return z end function prevfloat(x::MPFRFloat) z = MPFRFloat(x) - ccall((:mpfr_nextbelow, :libmpfr), Int32, (Ptr{Void},), z.mpfr) != 0 + ccall((:mpfr_nextbelow, :libmpfr), Int32, (Ptr{mpfr_struct},), &(z.mpfr)) != 0 return z end @@ -424,7 +431,7 @@ function round(x::MPFRFloat, prec::Int) end prec = int(ceil(log2(10^prec))) z = MPFRFloat(x) - ccall((:mpfr_prec_round, :libmpfr), Int32, (Ptr{Void}, Int, Int32), z.mpfr, prec, ROUNDING_MODE[end]) + ccall((:mpfr_prec_round, :libmpfr), Int32, (Ptr{mpfr_struct}, Int, Int32), &(z.mpfr), prec, ROUNDING_MODE[end]) return z end @@ -432,7 +439,7 @@ function string(x::MPFRFloat) lng = 128 for i = 1:2 z = Array(Uint8, lng) - lng = ccall((:mpfr_snprintf,:libmpfr), Int32, (Ptr{Uint8}, Uint, Ptr{Uint8}, Ptr{Void}...), z, lng, "%.Re", x.mpfr) + lng = ccall((:mpfr_snprintf,:libmpfr), Int32, (Ptr{Uint8}, Uint, Ptr{Uint8}, Ptr{mpfr_struct}...), z, lng, "%.Re", &(x.mpfr)) if lng < 128 || i == 2 return bytestring(convert(Ptr{Uint8}, z[1:lng])) end From 94ba263843ae698752127ef435a1efc9fbc1560f Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Thu, 11 Apr 2013 18:38:42 -0300 Subject: [PATCH 08/31] Change default precision of MPFRFloat to 256 bits As discussed in #2814 --- base/mpfr.jl | 4 +-- test/mpfr.jl | 100 +++++++++++++++++++++++++++------------------------ 2 files changed, 56 insertions(+), 48 deletions(-) diff --git a/base/mpfr.jl b/base/mpfr.jl index 34b19ce6739cc..be986dca632f8 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -21,7 +21,7 @@ import sech, csch, coth, acosh, asinh, atanh const ROUNDING_MODE = [0] -const DEFAULT_PRECISION = [53, 53] +const DEFAULT_PRECISION = [256] # Basic type and initialization definitions @@ -46,7 +46,7 @@ type MPFRFloat{N} <: FloatingPoint end end -MPFR_clear(mpfr::Vector{Int32}) = ccall((:mpfr_clear, :libmpfr), Void, (Ptr{mpfr_struct},), &mpfr) +MPFR_clear(mpfr::mpfr_struct) = ccall((:mpfr_clear, :libmpfr), Void, (Ptr{mpfr_struct},), &mpfr) function MPFRFloat(x::MPFRFloat) z = MPFRFloat{DEFAULT_PRECISION[end]}() diff --git a/test/mpfr.jl b/test/mpfr.jl index 03144d840bc66..bea824d0f2e32 100644 --- a/test/mpfr.jl +++ b/test/mpfr.jl @@ -2,21 +2,21 @@ x = MPFRFloat{53}() x = MPFRFloat(12) y = MPFRFloat(x) -@test x == y +@test_approx_eq x y y = MPFRFloat(0xc) -@test x == y +@test_approx_eq x y y = MPFRFloat(12.) -@test x == y +@test_approx_eq x y y = MPFRFloat(BigInt(12)) -@test x == y +@test_approx_eq x y y = MPFRFloat(BigFloat(12)) -@test x == y +@test_approx_eq x y y = MPFRFloat("12") -@test x == y +@test_approx_eq x y y = MPFRFloat(float32(12.)) -@test x == y +@test_approx_eq x y y = MPFRFloat(12//1) -@test x == y +@test_approx_eq x y # + x = MPFRFloat(12) @@ -215,22 +215,26 @@ end @test [x,y] == [MPFRFloat(12), MPFRFloat(42)] # log / log2 / log10 +with_precision(53) do x = MPFRFloat(42) -@test log(x) == log(42) -@test isinf(log(MPFRFloat(0))) -@test_fails log(MPFRFloat(-1)) -@test log2(x) == log2(42) -@test isinf(log2(MPFRFloat(0))) -@test_fails log2(MPFRFloat(-1)) -@test log10(x) == log10(42) -@test isinf(log10(MPFRFloat(0))) -@test_fails log10(MPFRFloat(-1)) + @test log(x) == log(42) + @test isinf(log(MPFRFloat(0))) + @test_fails log(MPFRFloat(-1)) + @test log2(x) == log2(42) + @test isinf(log2(MPFRFloat(0))) + @test_fails log2(MPFRFloat(-1)) + @test log10(x) == log10(42) + @test isinf(log10(MPFRFloat(0))) + @test_fails log10(MPFRFloat(-1)) +end # exp / exp2 / exp10 -x = MPFRFloat(10) -@test exp(x) == exp(10) -@test exp2(x) == 1024 -@test exp10(x) == 10000000000 +with_precision(53) do + x = MPFRFloat(10) + @test exp(x) == exp(10) + @test exp2(x) == 1024 + @test exp10(x) == 10000000000 +end # convert to integer types x = MPFRFloat(12.1) @@ -273,34 +277,38 @@ with_precision(256) do end # bessel functions -@test_approx_eq besselj(4, MPFRFloat(2)) besselj(4, 2.) -@test_approx_eq besselj0(MPFRFloat(2)) besselj0(2.) -@test_approx_eq besselj1(MPFRFloat(2)) besselj1(2.) -@test_approx_eq bessely(4, MPFRFloat(2)) bessely(4, 2.) -@test_approx_eq bessely0(MPFRFloat(2)) bessely0(2.) -@test_approx_eq bessely1(MPFRFloat(2)) bessely1(2.) +with_precision(53) do + @test_approx_eq besselj(4, MPFRFloat(2)) besselj(4, 2.) + @test_approx_eq besselj0(MPFRFloat(2)) besselj0(2.) + @test_approx_eq besselj1(MPFRFloat(2)) besselj1(2.) + @test_approx_eq bessely(4, MPFRFloat(2)) bessely(4, 2.) + @test_approx_eq bessely0(MPFRFloat(2)) bessely0(2.) + @test_approx_eq bessely1(MPFRFloat(2)) bessely1(2.) +end # trigonometric functions -for f in (:sin,:cos,:tan,:sec,:csc,:cot,:acos,:asin,:atan, - :cosh,:sinh,:tanh,:sech,:csch,:coth,:asinh), - j in (-1., -0.5, -0.25, .25, .5, 1.) - @eval begin - @test_approx_eq ($f)(MPFRFloat($j)) ($f)($j) +with_precision(53) do + for f in (:sin,:cos,:tan,:sec,:csc,:cot,:acos,:asin,:atan, + :cosh,:sinh,:tanh,:sech,:csch,:coth,:asinh), + j in (-1., -0.5, -0.25, .25, .5, 1.) + @eval begin + @test_approx_eq ($f)(MPFRFloat($j)) ($f)($j) + end end -end -for f in (:acos,:asin,:acosh,:atanh), - j in (-2, -1.5) - @eval begin - @test_fails ($f)(MPFRFloat($j)) + for f in (:acos,:asin,:acosh,:atanh), + j in (-2, -1.5) + @eval begin + @test_fails ($f)(MPFRFloat($j)) + end end -end -for f in (:sin,:cos,:tan,:sec,:csc,:cot,:cosh,:sinh,:tanh, - :sech,:csch,:coth,:acosh,:asinh), - j in (1., 1.5, 1.9) - @eval begin - @test_approx_eq ($f)(MPFRFloat($j)) ($f)($j) + for f in (:sin,:cos,:tan,:sec,:csc,:cot,:cosh,:sinh,:tanh, + :sech,:csch,:coth,:acosh,:asinh), + j in (1., 1.5, 1.9) + @eval begin + @test_approx_eq ($f)(MPFRFloat($j)) ($f)($j) + end + end + for j in (.25, .5) + @test_approx_eq atanh(MPFRFloat(j)) atanh(j) end -end -for j in (.25, .5) - @test_approx_eq atanh(MPFRFloat(j)) atanh(j) end From 9bff27344ccd12092f26bef4f4473c7ccca6f94b Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Sat, 13 Apr 2013 01:16:24 -0300 Subject: [PATCH 09/31] Rename precision-related functions and add them to Float32 and Float64 Now get_precision is defined for all T <: FloatingPoint, and returns 24 for Float32 and 53 for Float64 (the effective number of bits in the mantissa, taking in account the implicit leading bit. get_bigfloat_precision and set_bigfloat_precision are used to get and set the defaults for all BigFloats, and the BigComplex case is analogous. --- base/exports.jl | 7 +++---- base/floatfuncs.jl | 4 ++++ base/mpc.jl | 31 ++++++++++++------------------- base/mpfr.jl | 24 ++++++++++++------------ test/mpfr.jl | 36 ++++++++++++++++++------------------ 5 files changed, 49 insertions(+), 53 deletions(-) diff --git a/base/exports.jl b/base/exports.jl index 16df377045381..9b280c3bc403c 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -826,13 +826,12 @@ export # precision exp10, - prec, - prec2, get_precision, + get_bigfloat_precision, get_complex_precision, - set_precision, + set_bigfloat_precision, set_complex_precision, - with_precision, + with_bigfloat_precision, with_complex_precision, # statistics diff --git a/base/floatfuncs.jl b/base/floatfuncs.jl index 6eb85d352fe7f..4bcc6a6aa9591 100644 --- a/base/floatfuncs.jl +++ b/base/floatfuncs.jl @@ -31,6 +31,10 @@ maxintfloat() = maxintfloat(Float64) integer_valued(x::FloatingPoint) = (trunc(x)==x)&isfinite(x) +## precision, as defined by the effective number of bits in the mantissa ## +get_precision(::Float32) = 24 +get_precision(::Float64) = 53 + num2hex(x::Float32) = hex(box(Uint32,unbox(Float32,x)),8) num2hex(x::Float64) = hex(box(Uint64,unbox(Float64,x)),16) diff --git a/base/mpc.jl b/base/mpc.jl index b5a93f274fd37..17e4d097413dd 100644 --- a/base/mpc.jl +++ b/base/mpc.jl @@ -4,15 +4,14 @@ export # Types MPCComplex, # Functions - prec2, - get_complex_precision, - set_complex_precision, - with_complex_precision + get_bigcomplex_precision, + set_bigcomplex_precision, + with_bigcomplex_precision import Base: (*), +, -, /, <, <<, >>, <=, ==, >, >=, ^, (~), (&), (|), ($), cmp, complex, convert, div, imag, integer_valued, isfinite, isinf, isnan, - promote_rule, real, show, showcompact, sqrt, string, prec + promote_rule, real, show, showcompact, sqrt, string, get_precision const ROUNDING_MODE = 0 const DEFAULT_PRECISION = [53, 53] @@ -208,38 +207,32 @@ end # Utility functions ==(x::MPCComplex, y::MPCComplex) = ccall((:mpc_cmp, :libmpc), Int32, (Ptr{Void}, Ptr{Void}), x.mpc, y.mpc) == 0 - -# TODO: decide if prec and prec2 should be just one method or not. -function prec(x::MPCComplex) - return ccall((:mpc_get_prec, :libmpc), Int, (Ptr{Void},), x.mpc) -end - -function prec2(x::MPCComplex) +function get_precision(x::MPCComplex) a = [0] b = [0] ccall((:mpc_get_prec2, :libmpc), Int, (Ptr{Int}, Ptr{Int}, Ptr{Void}), a, b, x.mpc) return (a[1],b[1]) end -get_complex_precision() = (DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]) -function set_complex_precision(x::Int, y::Int) +get_bigcomplex_precision() = (DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]) +function set_bigcomplex_precision(x::Int, y::Int) if x < 2 throw(DomainError()) end DEFAULT_PRECISION[1], DEFAULT_PRECISION[end] = x, y end -set_complex_precision(x::(Int,Int)) = set_complex_precision(x...) +set_bigcomplex_precision(x::(Int,Int)) = set_bigcomplex_precision(x...) iscomplex(::MPCComplex) = true isfinite(x::MPCComplex) = isfinite(real(x)) && isfinite(imag(x)) isinf(x::MPCComplex) = !isfinite(x) integer_valued(x::MPCComplex) = imag(x) == 0 && integer_valued(real(x)) -function with_complex_precision(f::Function, realprec::Integer, imagprec::Integer) - old_precision = get_complex_precision() - set_complex_precision(realprec, imagprec) +function with_bigcomplex_precision(f::Function, realprec::Integer, imagprec::Integer) + old_precision = get_bigcomplex_precision() + set_bigcomplex_precision(realprec, imagprec) ret = f() - set_complex_precision(old_precision) + set_bigcomplex_precision(old_precision) return ret end diff --git a/base/mpfr.jl b/base/mpfr.jl index be986dca632f8..3633c20a0cebf 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -5,10 +5,9 @@ export MPFRFloat, # Functions exp10, - prec, - get_precision, - set_precision, - with_precision + get_bigfloat_precision, + set_bigfloat_precision, + with_bigfloat_precision import Base: (*), +, -, /, <, <=, ==, >, >=, ^, besselj, besselj0, besselj1, @@ -16,6 +15,7 @@ import exponent, factorial, floor, integer_valued, iround, isfinite, isinf, isnan, log, log2, log10, max, min, mod, modf, nextfloat, prevfloat, promote_rule, rem, round, show, showcompact, sum, sqrt, string, trunc, + get_precision, # import trigonometric functions sin, cos, tan, sec, csc, cot, acos, asin, atan, cosh, sinh, tanh, sech, csch, coth, acosh, asinh, atanh @@ -348,12 +348,12 @@ end <(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_less_p, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}), &(x.mpfr), &(y.mpfr)) != 0 >(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_greater_p, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}), &(x.mpfr), &(y.mpfr)) != 0 -function prec(x::MPFRFloat) +function get_precision(x::MPFRFloat) return ccall((:mpfr_get_prec, :libmpfr), Int, (Ptr{mpfr_struct},), &(x.mpfr)) end -get_precision() = DEFAULT_PRECISION[end] -function set_precision(x::Int) +get_bigfloat_precision() = DEFAULT_PRECISION[end] +function set_bigfloat_precision(x::Int) if x < 2 throw(DomainError()) end @@ -417,11 +417,11 @@ function prevfloat(x::MPFRFloat) return z end -function with_precision(f::Function, precision::Integer) - old_precision = get_precision() - set_precision(precision) +function with_bigfloat_precision(f::Function, precision::Integer) + old_precision = get_bigfloat_precision() + set_bigfloat_precision(precision) ret = f() - set_precision(old_precision) + set_bigfloat_precision(old_precision) return ret end @@ -446,7 +446,7 @@ function string(x::MPFRFloat) end end -show(io::IO, b::MPFRFloat) = print(io, string(b) * " with $(prec(b)) bits of precision") +show(io::IO, b::MPFRFloat) = print(io, string(b) * " with $(get_precision(b)) bits of precision") showcompact(io::IO, b::MPFRFloat) = print(io, string(b)) end #module diff --git a/test/mpfr.jl b/test/mpfr.jl index bea824d0f2e32..73b4756b83ffd 100644 --- a/test/mpfr.jl +++ b/test/mpfr.jl @@ -107,29 +107,29 @@ x = MPFRFloat(15.674) @test_fails sqrt(MPFRFloat(-1)) # precision -old_precision = get_precision() +old_precision = get_bigfloat_precision() x = MPFRFloat(0) -@test prec(x) == old_precision -set_precision(256) +@test get_precision(x) == old_precision +set_bigfloat_precision(256) x = MPFRFloat(0) -@test prec(x) == 256 -set_precision(old_precision) -z = with_precision(240) do +@test get_precision(x) == 256 +set_bigfloat_precision(old_precision) +z = with_bigfloat_precision(240) do z = x + 20 return z end @test float(z) == 20. -@test prec(z) == 240 +@test get_precision(z) == 240 x = MPFRFloat(12) -@test prec(x) == old_precision -@test_fails set_precision(1) +@test get_precision(x) == old_precision +@test_fails set_bigfloat_precision(1) # integer_valued @test integer_valued(MPFRFloat(12)) @test !integer_valued(MPFRFloat(12.12)) # nextfloat / prevfloat -with_precision(53) do +with_bigfloat_precision(53) do x = MPFRFloat(12.12) @test MPFRFloat(nextfloat(12.12)) == nextfloat(x) @test MPFRFloat(prevfloat(12.12)) == prevfloat(x) @@ -174,7 +174,7 @@ y = modf(x) @test (isnan(y[1]), isinf(y[2])) == (true, true) # rem -with_precision(53) do +with_bigfloat_precision(53) do x = MPFRFloat(2) y = MPFRFloat(1.67) @test rem(x,y) == rem(2, 1.67) @@ -209,13 +209,13 @@ big_array = ones(MPFRFloat, 100) # promotion # the array converts everyone to the DEFAULT_PRECISION! x = MPFRFloat(12) -y = with_precision(60) do +y = with_bigfloat_precision(60) do MPFRFloat(42) end @test [x,y] == [MPFRFloat(12), MPFRFloat(42)] # log / log2 / log10 -with_precision(53) do +with_bigfloat_precision(53) do x = MPFRFloat(42) @test log(x) == log(42) @test isinf(log(MPFRFloat(0))) @@ -229,7 +229,7 @@ x = MPFRFloat(42) end # exp / exp2 / exp10 -with_precision(53) do +with_bigfloat_precision(53) do x = MPFRFloat(10) @test exp(x) == exp(10) @test exp2(x) == 1024 @@ -252,7 +252,7 @@ y = MPFRFloat(42) # iround x = MPFRFloat(42.42) -y = with_precision(256) do +y = with_bigfloat_precision(256) do MPFRFloat("9223372036854775809.2324") end z = BigInt("9223372036854775809") @@ -267,7 +267,7 @@ z = BigInt("9223372036854775809") @test typeof(iround(Uint, x)) == Uint && iround(Uint, x) == 0x2a # factorial -with_precision(256) do +with_bigfloat_precision(256) do x = MPFRFloat(42) @test factorial(x) == factorial(BigInt(42)) x = MPFRFloat(10) @@ -277,7 +277,7 @@ with_precision(256) do end # bessel functions -with_precision(53) do +with_bigfloat_precision(53) do @test_approx_eq besselj(4, MPFRFloat(2)) besselj(4, 2.) @test_approx_eq besselj0(MPFRFloat(2)) besselj0(2.) @test_approx_eq besselj1(MPFRFloat(2)) besselj1(2.) @@ -287,7 +287,7 @@ with_precision(53) do end # trigonometric functions -with_precision(53) do +with_bigfloat_precision(53) do for f in (:sin,:cos,:tan,:sec,:csc,:cot,:acos,:asin,:atan, :cosh,:sinh,:tanh,:sech,:csch,:coth,:asinh), j in (-1., -0.5, -0.25, .25, .5, 1.) From 430907873e4ccf7bfb83ae09b0ff2782b6176d03 Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Sat, 13 Apr 2013 01:54:27 -0300 Subject: [PATCH 10/31] Update MPCComplex to use a precise mpc_struct As using two mpfr_structs doesn't work, I decided to expand them directly into two groups of four elements (two longs, an int and a pointer). They could be useful if we ever need to implement efficient in-place algorithms, as they can be directly extracted and manipulated as MPFRFloats. --- base/mpc.jl | 71 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/base/mpc.jl b/base/mpc.jl index 17e4d097413dd..9814a66c09334 100644 --- a/base/mpc.jl +++ b/base/mpc.jl @@ -18,25 +18,39 @@ const DEFAULT_PRECISION = [53, 53] # Basic type and initialization definitions -immutable MPCComplex{N,P} <: Number - mpc::Vector{Int32} +type mpc_struct + # Real MPFR part + reprec::Clong + resign::Cint + reexp::Clong + red::Ptr{Void} + # Imaginary MPFR part + imprec::Clong + imsign::Cint + imexp::Clong + imd::Ptr{Void} +end + +type MPCComplex{N,P} <: Number + mpc::mpc_struct function MPCComplex() if N < 2 || P < 2 error("Invalid precision") end - z = Array(Int32, 16) - ccall((:mpc_init3,:libmpc), Void, (Ptr{Void}, Int32, Int32), z, N, P) + z = mpc_struct(convert(Clong, 0), convert(Cint, 0), convert(Clong, 0), + C_NULL, convert(Clong, 0), convert(Cint, 0), convert(Clong, 0), C_NULL) + ccall((:mpc_init3,:libmpc), Void, (Ptr{mpc_struct}, Clong, Clong), &z, N, P) b = new(z) finalizer(b.mpc, MPC_clear) return b end end -MPC_clear(mpc::Vector{Int32}) = ccall((:mpc_clear, :libmpc), Void, (Ptr{Void},), mpc) +MPC_clear(mpc::mpc_struct) = ccall((:mpc_clear, :libmpc), Void, (Ptr{mpc_struct},), &mpc) function MPCComplex{N,P}(x::MPCComplex{N,P}) z = MPCComplex{N,P}() - ccall((:mpc_set, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpc, ROUNDING_MODE) + ccall((:mpc_set, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Int32), &(z.mpc), &(x.mpc), ROUNDING_MODE) return z end @@ -45,7 +59,7 @@ for (fJ, fC) in ((:si,:Int), (:ui,:Uint), (:d,:Float64)) @eval begin function MPCComplex(x::($fC)) z = MPCComplex{DEFAULT_PRECISION[1], DEFAULT_PRECISION[end]}() - ccall(($(string(:mpc_set_,fJ)), :libmpc), Int32, (Ptr{Void}, ($fC), Int32), z.mpc, x, ROUNDING_MODE) + ccall(($(string(:mpc_set_,fJ)), :libmpc), Int32, (Ptr{mpc_struct}, ($fC), Int32), &(z.mpc), x, ROUNDING_MODE) return z end end @@ -53,25 +67,25 @@ end function MPCComplex(x::BigInt) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_z, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpc, &(x.mpz), ROUNDING_MODE) + ccall((:mpc_set_z, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Int32), &(z.mpc), &(x.mpz), ROUNDING_MODE) return z end function MPCComplex(x::BigFloat) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_f, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpf, ROUNDING_MODE) + ccall((:mpc_set_f, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Int32), &(z.mpc), x.mpf, ROUNDING_MODE) return z end function MPCComplex(x::MPFRFloat) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_fr, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpc, &(x.mpfr), ROUNDING_MODE) + ccall((:mpc_set_fr, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Int32), &(z.mpc), &(x.mpfr), ROUNDING_MODE) return z end function MPCComplex(x::String, base::Int) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - err = ccall((:mpc_set_str, :libmpc), Int32, (Ptr{Void}, Ptr{Uint8}, Int32, Int32), z.mpc, x, base, ROUNDING_MODE) + err = ccall((:mpc_set_str, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Uint8}, Int32, Int32), &(z.mpc), x, base, ROUNDING_MODE) if err != 0; error("Invalid input"); end return z end @@ -96,8 +110,8 @@ convert(::Type{MPCComplex}, x::Complex) = MPCComplex(x) convert{N,P}(::Type{MPCComplex{N,P}}, x::ImaginaryUnit) = MPCComplex(x) convert(::Type{MPCComplex}, x::ImaginaryUnit) = MPCComplex(x) -convert(::Type{Float64}, x::MPCComplex) = ccall((:mpc_get_d,:libmpc), Float64, (Ptr{Void},), x.mpc) -convert(::Type{Float32}, x::MPCComplex) = ccall((:mpc_get_flt,:libmpc), Float32, (Ptr{Void},), x.mpc) +convert(::Type{Float64}, x::MPCComplex) = ccall((:mpc_get_d,:libmpc), Float64, (Ptr{mpc_struct},), &(x.mpc)) +convert(::Type{Float32}, x::MPCComplex) = ccall((:mpc_get_flt,:libmpc), Float32, (Ptr{mpc_struct},), &(x.mpc)) #convert(::Type{FloatingPoint}, x::BigInt) = MPCComplex(x) promote_rule{T<:Real,N,P}(::Type{MPCComplex{N,P}}, ::Type{T}) = MPCComplex{N,P} @@ -118,7 +132,7 @@ for (fJ, fC) in ((:si,:Int), (:ui,:Uint), (:d,:Float64)) @eval begin function MPCComplex(x::($fC), y::($fC)) z = MPCComplex{DEFAULT_PRECISION[1], DEFAULT_PRECISION[end]}() - ccall(($(string(:mpc_set_,fJ,'_',fJ)), :libmpc), Int32, (Ptr{Void}, ($fC), ($fC), Int32), z.mpc, x, y, ROUNDING_MODE) + ccall(($(string(:mpc_set_,fJ,'_',fJ)), :libmpc), Int32, (Ptr{mpc_struct}, ($fC), ($fC), Int32), &(z.mpc), x, y, ROUNDING_MODE) return z end end @@ -126,19 +140,19 @@ end function MPCComplex(x::BigInt, y::BigInt) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_z_z, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpc, &(x.mpz), &(y.mpz), ROUNDING_MODE) + ccall((:mpc_set_z_z, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Ptr{Void}, Int32), &(z.mpc), &(x.mpz), &(y.mpz), ROUNDING_MODE) return z end function MPCComplex(x::BigFloat, y::BigFloat) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_f_f, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpf, y.mpf, ROUNDING_MODE) + ccall((:mpc_set_f_f, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Ptr{Void}, Int32), &(z.mpc), x.mpf, y.mpf, ROUNDING_MODE) return z end function MPCComplex(x::MPFRFloat, y::MPFRFloat) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_fr_fr, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpc, &(x.mpfr), &(y.mpfr), ROUNDING_MODE) + ccall((:mpc_set_fr_fr, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Ptr{Void}, Int32), &(z.mpc), &(x.mpfr), &(y.mpfr), ROUNDING_MODE) return z end @@ -161,7 +175,7 @@ for (fJ, fC) in ((:+,:add), (:-,:sub), (:*,:mul), (:/,:div), (:^, :pow)) @eval begin function ($fJ)(x::MPCComplex, y::MPCComplex) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall(($(string(:mpc_,fC)),:libmpc), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpc, y.mpc, ROUNDING_MODE) + ccall(($(string(:mpc_,fC)),:libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Ptr{mpc_struct}, Int32), &(z.mpc), &(x.mpc), &(y.mpc), ROUNDING_MODE) return z end end @@ -169,17 +183,17 @@ end function -(x::MPCComplex) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_neg, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpc, ROUNDING_MODE) + ccall((:mpc_neg, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Int32), &(z.mpc), &(x.mpc), ROUNDING_MODE) return z end function cmp(x::MPCComplex, y::MPCComplex) - ccall((:mpc_cmp, :libmpc), Int32, (Ptr{Void}, Ptr{Void}), x.mpc, y.mpc) + ccall((:mpc_cmp, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}), &(x.mpc), &(y.mpc)) end function sqrt(x::MPCComplex) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_sqrt, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpc, ROUNDING_MODE) + ccall((:mpc_sqrt, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Int32), &(z.mpc), &(x.mpc), ROUNDING_MODE) if isnan(z) throw(DomainError()) end @@ -188,29 +202,29 @@ end function ^(x::MPCComplex, y::Uint) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_pow_ui, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Uint, Int32), z.mpc, x.mpc, y, ROUNDING_MODE) + ccall((:mpc_pow_ui, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Uint, Int32), &(z.mpc), &(x.mpc), y, ROUNDING_MODE) return z end function ^(x::MPCComplex, y::Int) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_pow_si, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int, Int32), z.mpc, x.mpc, y, ROUNDING_MODE) + ccall((:mpc_pow_si, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Int, Int32), &(z.mpc), &(x.mpc), y, ROUNDING_MODE) return z end function ^(x::MPCComplex, y::BigInt) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_pow_z, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Ptr{Void}, Int32), z.mpc, x.mpc, &(y.mpz), ROUNDING_MODE) + ccall((:mpc_pow_z, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Ptr{Void}, Int32), &(z.mpc), &(x.mpc), &(y.mpz), ROUNDING_MODE) return z end # Utility functions -==(x::MPCComplex, y::MPCComplex) = ccall((:mpc_cmp, :libmpc), Int32, (Ptr{Void}, Ptr{Void}), x.mpc, y.mpc) == 0 +==(x::MPCComplex, y::MPCComplex) = ccall((:mpc_cmp, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}), &(x.mpc), &(y.mpc)) == 0 function get_precision(x::MPCComplex) a = [0] b = [0] - ccall((:mpc_get_prec2, :libmpc), Int, (Ptr{Int}, Ptr{Int}, Ptr{Void}), a, b, x.mpc) + ccall((:mpc_get_prec2, :libmpc), Int, (Ptr{Int}, Ptr{Int}, Ptr{mpc_struct}), a, b, &(x.mpc)) return (a[1],b[1]) end @@ -223,7 +237,6 @@ function set_bigcomplex_precision(x::Int, y::Int) end set_bigcomplex_precision(x::(Int,Int)) = set_bigcomplex_precision(x...) -iscomplex(::MPCComplex) = true isfinite(x::MPCComplex) = isfinite(real(x)) && isfinite(imag(x)) isinf(x::MPCComplex) = !isfinite(x) integer_valued(x::MPCComplex) = imag(x) == 0 && integer_valued(real(x)) @@ -238,13 +251,13 @@ end function imag{N,P}(x::MPCComplex{N,P}) z = MPFRFloat{N}() - ccall((:mpc_imag, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), &(z.mpfr), x.mpc, ROUNDING_MODE) + ccall((:mpc_imag, :libmpc), Int32, (Ptr{Void}, Ptr{mpc_struct}, Int32), &(z.mpfr), &(x.mpc), ROUNDING_MODE) return z end function real{N,P}(x::MPCComplex{N,P}) z = MPFRFloat{N}() - ccall((:mpc_real, :libmpc), Int32, (Ptr{Void}, Ptr{Void}, Int32), &(z.mpfr), x.mpc, ROUNDING_MODE) + ccall((:mpc_real, :libmpc), Int32, (Ptr{Void}, Ptr{mpc_struct}, Int32), &(z.mpfr), &(x.mpc), ROUNDING_MODE) return z end From cd20424e5ec26577e07b74045b744116424653a7 Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Sat, 13 Apr 2013 02:52:07 -0300 Subject: [PATCH 11/31] Flexibilize the ROUNDING_MODE for MPCComplex numbers --- base/exports.jl | 6 +++--- base/mpc.jl | 41 +++++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/base/exports.jl b/base/exports.jl index 9b280c3bc403c..a03fac3290d78 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -828,11 +828,11 @@ export exp10, get_precision, get_bigfloat_precision, - get_complex_precision, + get_bigcomplex_precision, set_bigfloat_precision, - set_complex_precision, + set_bigcomplex_precision, with_bigfloat_precision, - with_complex_precision, + with_bigcomplex_precision, # statistics cor, diff --git a/base/mpc.jl b/base/mpc.jl index 9814a66c09334..b5c745b7aa1a8 100644 --- a/base/mpc.jl +++ b/base/mpc.jl @@ -13,7 +13,7 @@ import complex, convert, div, imag, integer_valued, isfinite, isinf, isnan, promote_rule, real, show, showcompact, sqrt, string, get_precision -const ROUNDING_MODE = 0 +const ROUNDING_MODE = [0] const DEFAULT_PRECISION = [53, 53] # Basic type and initialization definitions @@ -50,7 +50,7 @@ MPC_clear(mpc::mpc_struct) = ccall((:mpc_clear, :libmpc), Void, (Ptr{mpc_struct} function MPCComplex{N,P}(x::MPCComplex{N,P}) z = MPCComplex{N,P}() - ccall((:mpc_set, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Int32), &(z.mpc), &(x.mpc), ROUNDING_MODE) + ccall((:mpc_set, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Int32), &(z.mpc), &(x.mpc), ROUNDING_MODE[end]) return z end @@ -59,7 +59,7 @@ for (fJ, fC) in ((:si,:Int), (:ui,:Uint), (:d,:Float64)) @eval begin function MPCComplex(x::($fC)) z = MPCComplex{DEFAULT_PRECISION[1], DEFAULT_PRECISION[end]}() - ccall(($(string(:mpc_set_,fJ)), :libmpc), Int32, (Ptr{mpc_struct}, ($fC), Int32), &(z.mpc), x, ROUNDING_MODE) + ccall(($(string(:mpc_set_,fJ)), :libmpc), Int32, (Ptr{mpc_struct}, ($fC), Int32), &(z.mpc), x, ROUNDING_MODE[end]) return z end end @@ -67,25 +67,25 @@ end function MPCComplex(x::BigInt) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_z, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Int32), &(z.mpc), &(x.mpz), ROUNDING_MODE) + ccall((:mpc_set_z, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Int32), &(z.mpc), &(x.mpz), ROUNDING_MODE[end]) return z end function MPCComplex(x::BigFloat) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_f, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Int32), &(z.mpc), x.mpf, ROUNDING_MODE) + ccall((:mpc_set_f, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Int32), &(z.mpc), x.mpf, ROUNDING_MODE[end]) return z end function MPCComplex(x::MPFRFloat) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_fr, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Int32), &(z.mpc), &(x.mpfr), ROUNDING_MODE) + ccall((:mpc_set_fr, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Int32), &(z.mpc), &(x.mpfr), ROUNDING_MODE[end]) return z end function MPCComplex(x::String, base::Int) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - err = ccall((:mpc_set_str, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Uint8}, Int32, Int32), &(z.mpc), x, base, ROUNDING_MODE) + err = ccall((:mpc_set_str, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Uint8}, Int32, Int32), &(z.mpc), x, base, ROUNDING_MODE[end]) if err != 0; error("Invalid input"); end return z end @@ -132,7 +132,7 @@ for (fJ, fC) in ((:si,:Int), (:ui,:Uint), (:d,:Float64)) @eval begin function MPCComplex(x::($fC), y::($fC)) z = MPCComplex{DEFAULT_PRECISION[1], DEFAULT_PRECISION[end]}() - ccall(($(string(:mpc_set_,fJ,'_',fJ)), :libmpc), Int32, (Ptr{mpc_struct}, ($fC), ($fC), Int32), &(z.mpc), x, y, ROUNDING_MODE) + ccall(($(string(:mpc_set_,fJ,'_',fJ)), :libmpc), Int32, (Ptr{mpc_struct}, ($fC), ($fC), Int32), &(z.mpc), x, y, ROUNDING_MODE[end]) return z end end @@ -140,19 +140,19 @@ end function MPCComplex(x::BigInt, y::BigInt) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_z_z, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Ptr{Void}, Int32), &(z.mpc), &(x.mpz), &(y.mpz), ROUNDING_MODE) + ccall((:mpc_set_z_z, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Ptr{Void}, Int32), &(z.mpc), &(x.mpz), &(y.mpz), ROUNDING_MODE[end]) return z end function MPCComplex(x::BigFloat, y::BigFloat) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_f_f, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Ptr{Void}, Int32), &(z.mpc), x.mpf, y.mpf, ROUNDING_MODE) + ccall((:mpc_set_f_f, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Ptr{Void}, Int32), &(z.mpc), x.mpf, y.mpf, ROUNDING_MODE[end]) return z end function MPCComplex(x::MPFRFloat, y::MPFRFloat) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_fr_fr, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Ptr{Void}, Int32), &(z.mpc), &(x.mpfr), &(y.mpfr), ROUNDING_MODE) + ccall((:mpc_set_fr_fr, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Ptr{Void}, Int32), &(z.mpc), &(x.mpfr), &(y.mpfr), ROUNDING_MODE[end]) return z end @@ -175,7 +175,7 @@ for (fJ, fC) in ((:+,:add), (:-,:sub), (:*,:mul), (:/,:div), (:^, :pow)) @eval begin function ($fJ)(x::MPCComplex, y::MPCComplex) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall(($(string(:mpc_,fC)),:libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Ptr{mpc_struct}, Int32), &(z.mpc), &(x.mpc), &(y.mpc), ROUNDING_MODE) + ccall(($(string(:mpc_,fC)),:libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Ptr{mpc_struct}, Int32), &(z.mpc), &(x.mpc), &(y.mpc), ROUNDING_MODE[end]) return z end end @@ -183,7 +183,7 @@ end function -(x::MPCComplex) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_neg, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Int32), &(z.mpc), &(x.mpc), ROUNDING_MODE) + ccall((:mpc_neg, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Int32), &(z.mpc), &(x.mpc), ROUNDING_MODE[end]) return z end @@ -193,7 +193,7 @@ end function sqrt(x::MPCComplex) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_sqrt, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Int32), &(z.mpc), &(x.mpc), ROUNDING_MODE) + ccall((:mpc_sqrt, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Int32), &(z.mpc), &(x.mpc), ROUNDING_MODE[end]) if isnan(z) throw(DomainError()) end @@ -202,19 +202,19 @@ end function ^(x::MPCComplex, y::Uint) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_pow_ui, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Uint, Int32), &(z.mpc), &(x.mpc), y, ROUNDING_MODE) + ccall((:mpc_pow_ui, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Uint, Int32), &(z.mpc), &(x.mpc), y, ROUNDING_MODE[end]) return z end function ^(x::MPCComplex, y::Int) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_pow_si, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Int, Int32), &(z.mpc), &(x.mpc), y, ROUNDING_MODE) + ccall((:mpc_pow_si, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Int, Int32), &(z.mpc), &(x.mpc), y, ROUNDING_MODE[end]) return z end function ^(x::MPCComplex, y::BigInt) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_pow_z, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Ptr{Void}, Int32), &(z.mpc), &(x.mpc), &(y.mpz), ROUNDING_MODE) + ccall((:mpc_pow_z, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Ptr{Void}, Int32), &(z.mpc), &(x.mpc), &(y.mpz), ROUNDING_MODE[end]) return z end @@ -248,22 +248,23 @@ function with_bigcomplex_precision(f::Function, realprec::Integer, imagprec::Int set_bigcomplex_precision(old_precision) return ret end +with_bigcomplex_precision(f::Function, prec::Integer) = with_bigcomplex_precision(f, prec, prec) function imag{N,P}(x::MPCComplex{N,P}) z = MPFRFloat{N}() - ccall((:mpc_imag, :libmpc), Int32, (Ptr{Void}, Ptr{mpc_struct}, Int32), &(z.mpfr), &(x.mpc), ROUNDING_MODE) + ccall((:mpc_imag, :libmpc), Int32, (Ptr{Void}, Ptr{mpc_struct}, Int32), &(z.mpfr), &(x.mpc), ROUNDING_MODE[end]) return z end function real{N,P}(x::MPCComplex{N,P}) z = MPFRFloat{N}() - ccall((:mpc_real, :libmpc), Int32, (Ptr{Void}, Ptr{mpc_struct}, Int32), &(z.mpfr), &(x.mpc), ROUNDING_MODE) + ccall((:mpc_real, :libmpc), Int32, (Ptr{Void}, Ptr{mpc_struct}, Int32), &(z.mpfr), &(x.mpc), ROUNDING_MODE[end]) return z end string(x::MPCComplex) = "$(string(real(x))) + $(string(imag(x)))im" -show(io::IO, b::MPCComplex) = print(io, string(b) * " with $(prec2(b)) bits of precision") +show(io::IO, b::MPCComplex) = print(io, string(b) * " with $(get_precision(b)) bits of precision") showcompact(io::IO, b::MPCComplex) = print(io, string(b)) end #module From 2d239523921f038fe97e120a9f0025ce3c80a358 Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Sat, 13 Apr 2013 03:41:15 -0300 Subject: [PATCH 12/31] Convert methods for other common complex types available These methods were written in order to avoid having to use real() or imag(), as they create a new MPFRFloat object. --- base/mpc.jl | 40 ++++++++++++++++++++++++++++++++++++---- test/mpc.jl | 13 +++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/base/mpc.jl b/base/mpc.jl index b5c745b7aa1a8..6726cab7cc9c6 100644 --- a/base/mpc.jl +++ b/base/mpc.jl @@ -110,10 +110,34 @@ convert(::Type{MPCComplex}, x::Complex) = MPCComplex(x) convert{N,P}(::Type{MPCComplex{N,P}}, x::ImaginaryUnit) = MPCComplex(x) convert(::Type{MPCComplex}, x::ImaginaryUnit) = MPCComplex(x) -convert(::Type{Float64}, x::MPCComplex) = ccall((:mpc_get_d,:libmpc), Float64, (Ptr{mpc_struct},), &(x.mpc)) -convert(::Type{Float32}, x::MPCComplex) = ccall((:mpc_get_flt,:libmpc), Float32, (Ptr{mpc_struct},), &(x.mpc)) -#convert(::Type{FloatingPoint}, x::BigInt) = MPCComplex(x) - +function convert(::Type{Complex{Float64}}, x::MPCComplex) + return complex( + ccall((:mpfr_get_d,:libmpfr), Float64, (Ptr{Void},), &(realref(x))), + ccall((:mpfr_get_d,:libmpfr), Float64, (Ptr{Void},), &(imagref(x)))) +end +function convert(::Type{Complex{Float32}}, x::MPCComplex) + return complex( + ccall((:mpfr_get_flt,:libmpfr), Float32, (Ptr{Void},), &(realref(x))), + ccall((:mpfr_get_flt,:libmpfr), Float32, (Ptr{Void},), &(imagref(x)))) +end +function convert(::Type{Complex{Int64}}, x::MPCComplex) + if realint(x) && imagint(x) + return complex( + ccall((:mpfr_get_si,:libmpfr), Int64, (Ptr{Void}, Int32), &(realref(x)), ROUNDING_MODE[end]), + ccall((:mpfr_get_si,:libmpfr), Int64, (Ptr{Void}, Int32), &(imagref(x)), ROUNDING_MODE[end])) + else + throw(InexactError()) + end +end +function convert(::Type{Complex{Int32}}, x::MPCComplex) + if realint(x) && imagint(x) + return complex( + int32(ccall((:mpfr_get_si,:libmpfr), Int64, (Ptr{Void}, Int32), &(realref(x)), ROUNDING_MODE[end])), + int32(ccall((:mpfr_get_si,:libmpfr), Int64, (Ptr{Void}, Int32), &(imagref(x)), ROUNDING_MODE[end]))) + else + throw(InexactError()) + end +end promote_rule{T<:Real,N,P}(::Type{MPCComplex{N,P}}, ::Type{T}) = MPCComplex{N,P} promote_rule{T<:Real}(::Type{MPCComplex}, ::Type{T}) = MPCComplex promote_rule{T<:Real,N,P}(::Type{MPCComplex{N,P}}, ::Type{Complex{T}}) = MPCComplex{N,P} @@ -267,4 +291,12 @@ string(x::MPCComplex) = "$(string(real(x))) + $(string(imag(x)))im" show(io::IO, b::MPCComplex) = print(io, string(b) * " with $(get_precision(b)) bits of precision") showcompact(io::IO, b::MPCComplex) = print(io, string(b)) +# Internal functions +# Unsafe for general use +realref(x::MPCComplex) = MPFR.mpfr_struct(x.mpc.reprec, x.mpc.resign, x.mpc.reexp, x.mpc.red) +imagref(x::MPCComplex) = MPFR.mpfr_struct(x.mpc.imprec, x.mpc.imsign, x.mpc.imexp, x.mpc.imd) +realint(x::MPCComplex) = ccall((:mpfr_integer_p, :libmpfr), Int32, (Ptr{Void},), &(realref(x))) != 0 +imagint(x::MPCComplex) = ccall((:mpfr_integer_p, :libmpfr), Int32, (Ptr{Void},), &(imagref(x))) != 0 + + end #module diff --git a/test/mpc.jl b/test/mpc.jl index b3355f6bde894..8792d679c2b4d 100644 --- a/test/mpc.jl +++ b/test/mpc.jl @@ -53,6 +53,19 @@ y = MPCComplex(x) @test real(x) == real(y) @test imag(x) == imag(y) +# conversion +with_bigcomplex_precision(53) do + x = MPCComplex(12, 42) + @test typeof(convert(Complex{Float64}, x)) == Complex{Float64} + @test typeof(convert(Complex{Float32}, x)) == Complex{Float32} + @test typeof(convert(Complex{Int64}, x)) == Complex{Int64} + @test typeof(convert(Complex{Int32}, x)) == Complex{Int32} + @test 12. + 42.0im == convert(Complex{Float64}, x) + @test 12f0 + 42f0im == convert(Complex{Float32}, x) + @test 12 + 42im == convert(Complex{Int64}, x) + @test 12 + 42im == convert(Complex{Int32}, x) +end + # + x = MPCComplex(12,42) @test (x + x) == MPCComplex(24, 84) From 38392cd5a5df5847546f210ba53f0540d64e89ef Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Sun, 14 Apr 2013 14:14:54 -0300 Subject: [PATCH 13/31] Use more efficient addition/subtraction/multiplication for ints/uints This also is the first function which tries to take in account that Clong is not always Int. --- base/bigint.jl | 44 ++++++++++++++++++++++++++ test/bigint.jl | 84 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 125 insertions(+), 3 deletions(-) diff --git a/base/bigint.jl b/base/bigint.jl index 52d49b8d594a0..be8ecf874130c 100644 --- a/base/bigint.jl +++ b/base/bigint.jl @@ -70,6 +70,50 @@ for (fJ, fC) in ((:+, :add), (:-,:sub), (:*, :mul), end end +# Basic arithmetic without promotion +function +(x::BigInt, c::Culong) + z = BigInt() + ccall((:__gmpz_add_ui, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}, Culong), &(z.mpz), &(x.mpz), c) + return z +end ++(c::Culong, x::BigInt) = x + c ++(c::Unsigned, x::BigInt) = x + convert(Culong, c) ++(x::BigInt, c::Unsigned) = x + convert(Culong, c) ++(x::BigInt, c::Signed) = c < 0 ? -(x, convert(Culong, -c)) : x + convert(Culong, c) ++(c::Signed, x::BigInt) = c < 0 ? -(x, convert(Culong, -c)) : x + convert(Culong, c) + +function -(x::BigInt, c::Culong) + z = BigInt() + ccall((:__gmpz_sub_ui, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}, Culong), &(z.mpz), &(x.mpz), c) + return z +end +function -(c::Culong, x::BigInt) + z = BigInt() + ccall((:__gmpz_ui_sub, :libgmp), Void, (Ptr{mpz_struct}, Culong, Ptr{mpz_struct}), &(z.mpz), c, &(x.mpz)) + return z +end +-(x::BigInt, c::Unsigned) = -(x, convert(Culong, c)) +-(c::Unsigned, x::BigInt) = -(convert(Culong, c), x) +-(x::BigInt, c::Signed) = c < 0 ? +(x, convert(Culong, -c)) : -(x, convert(Culong, c)) +-(c::Signed, x::BigInt) = c < 0 ? -(x + convert(Culong, -c)) : -(convert(Culong, c), x) + +function *(x::BigInt, c::Culong) + z = BigInt() + ccall((:__gmpz_mul_ui, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}, Culong), &(z.mpz), &(x.mpz), c) + return z +end +*(c::Culong, x::BigInt) = x * c +*(c::Unsigned, x::BigInt) = x * convert(Culong, c) +*(x::BigInt, c::Unsigned) = x * convert(Culong, c) +function *(x::BigInt, c::Clong) + z = BigInt() + ccall((:__gmpz_mul_si, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}, Culong), &(z.mpz), &(x.mpz), c) + return z +end +*(c::Clong, x::BigInt) = x * c +*(x::BigInt, c::Signed) = x * convert(Clong, c) +*(c::Signed, x::BigInt) = x * convert(Clong, c) + # unary ops for (fJ, fC) in ((:-, :neg), (:~, :com)) @eval begin diff --git a/test/bigint.jl b/test/bigint.jl index f8966d3884cc1..7d2bb707d75f9 100644 --- a/test/bigint.jl +++ b/test/bigint.jl @@ -54,18 +54,96 @@ end @test typeof(BigInt(BigInt(1))) == BigInt + +# Signed addition @test a+int8(1) == b @test a+int16(1) == b @test a+int32(1) == b @test a+int64(1) == b -#@test a+int128(1) == b - +@test int8(1)+ a == b +@test int16(1)+a == b +@test int32(1)+a == b +@test int64(1)+a == b +@test b+int8(-1) == a +@test b+int16(-1) == a +@test b+int32(-1) == a +@test b+int64(-1) == a +@test int8(-1)+ b == a +@test int16(-1)+b == a +@test int32(-1)+b == a +@test int64(-1)+b == a + +# Unsigned addition +@test a+true == b +@test a+uint8(1) == b +@test a+uint16(1) == b +@test a+uint32(1) == b +@test a+uint64(1) == b +@test true+a == b +@test uint8(1)+ a == b +@test uint16(1)+a == b +@test uint32(1)+a == b +@test uint64(1)+a == b + +# Signed subtraction +@test b-int8(1) == a +@test b-int16(1) == a +@test b-int32(1) == a +@test b-int64(1) == a +@test int8(1)- b == -a +@test int16(1)-b == -a +@test int32(1)-b == -a +@test int64(1)-b == -a +@test a-int8(-1) == b +@test a-int16(-1) == b +@test a-int32(-1) == b +@test a-int64(-1) == b +@test int8(-1)- a == -b +@test int16(-1)-a == -b +@test int32(-1)-a == -b +@test int64(-1)-a == -b + +# Unsigned subtraction @test a+true == b @test a+uint8(1) == b @test a+uint16(1) == b @test a+uint32(1) == b @test a+uint64(1) == b -#@test a+uint128(1) == b +@test true+a == b +@test uint8(1)+ a == b +@test uint16(1)+a == b +@test uint32(1)+a == b +@test uint64(1)+a == b + +# Signed multiplication +@test a*int8(1) == a +@test a*int16(1) == a +@test a*int32(1) == a +@test a*int64(1) == a +@test int8(1)* a == a +@test int16(1)*a == a +@test int32(1)*a == a +@test int64(1)*a == a +@test a*int8(-1) == -a +@test a*int16(-1) == -a +@test a*int32(-1) == -a +@test a*int64(-1) == -a +@test int8(-1)* a == -a +@test int16(-1)*a == -a +@test int32(-1)*a == -a +@test int64(-1)*a == -a + +# Unsigned multiplication +@test a*true == a +@test a*uint8(1) == a +@test a*uint16(1) == a +@test a*uint32(1) == a +@test a*uint64(1) == a +@test true*a == a +@test uint8(1)* a == a +@test uint16(1)*a == a +@test uint32(1)*a == a +@test uint64(1)*a == a @test a+BigInt(1) == b From d458148055510514d2533330b2eb9722c086e142 Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Sun, 21 Apr 2013 16:33:06 -0300 Subject: [PATCH 14/31] Scrap mpz_struct, as suggested by Jeff --- base/bigfloat.jl | 2 +- base/bigint.jl | 68 +++++++++++++++++++++++------------------------- base/mpc.jl | 6 ++--- base/mpfr.jl | 8 +++--- 4 files changed, 40 insertions(+), 44 deletions(-) diff --git a/base/bigfloat.jl b/base/bigfloat.jl index 747a259ae4ec6..e7701dab41965 100644 --- a/base/bigfloat.jl +++ b/base/bigfloat.jl @@ -44,7 +44,7 @@ end function BigFloat(x::BigInt) z = BigFloat() - ccall((:__gmpf_set_z, :libgmp), Void, (Ptr{Void}, Ptr{mpz_struct}), z.mpf, &(x.mpz)) + ccall((:__gmpf_set_z, :libgmp), Void, (Ptr{Void}, Ptr{BigInt}), z.mpf, &x) return z end diff --git a/base/bigint.jl b/base/bigint.jl index be8ecf874130c..e1eb54d01d467 100644 --- a/base/bigint.jl +++ b/base/bigint.jl @@ -1,38 +1,34 @@ type BigInt <: Integer - mpz::mpz_struct + alloc::Cint + size::Cint + d::Ptr{Void} function BigInt() - z = mpz_struct(int32(0), int32(0), C_NULL) - ccall((:__gmpz_init,:libgmp), Void, (Ptr{mpz_struct},), &z) - b = new(z) - finalizer(b.mpz, BigInt_clear) + b = new(zero(Cint), zero(Cint), C_NULL) + ccall((:__gmpz_init,:libgmp), Void, (Ptr{BigInt},), &b) + finalizer(b, BigInt_clear) return b end end +BigInt_clear(mpz::BigInt) = ccall((:__gmpz_clear, :libgmp), Void, (Ptr{BigInt},), &mpz) -BigInt_clear(mpz::mpz_struct) = ccall((:__gmpz_clear, :libgmp), Void, (Ptr{mpz_struct},), &mpz) -function BigInt(x::BigInt) - z = BigInt() - ccall((:__gmpz_set, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}), &(z.mpz), &(x.mpz)) - return z -end - +BigInt(x::BigInt) = x function BigInt(x::String) z = BigInt() - err = ccall((:__gmpz_set_str, :libgmp), Int32, (Ptr{mpz_struct}, Ptr{Uint8}, Int32), &(z.mpz), bytestring(x), 0) + err = ccall((:__gmpz_set_str, :libgmp), Int32, (Ptr{BigInt}, Ptr{Uint8}, Int32), &z, bytestring(x), 0) if err != 0; error("Invalid input"); end return z end function BigInt(x::Int) z = BigInt() - ccall((:__gmpz_set_si, :libgmp), Void, (Ptr{mpz_struct}, Int), &(z.mpz), x) + ccall((:__gmpz_set_si, :libgmp), Void, (Ptr{BigInt}, Int), &z, x) return z end function BigInt(x::Uint) z = BigInt() ccall((:__gmpz_set_ui, :libgmp), Void, - (Ptr{mpz_struct}, Uint), &(z.mpz), x) + (Ptr{BigInt}, Uint), &z, x) return z end @@ -49,10 +45,10 @@ end convert{T<:Integer}(::Type{BigInt}, x::T) = BigInt(x) convert(::Type{Int}, n::BigInt) = - ccall((:__gmpz_get_si, :libgmp), Int, (Ptr{mpz_struct},), &(n.mpz)) + ccall((:__gmpz_get_si, :libgmp), Int, (Ptr{BigInt},), &n) convert(::Type{Uint}, n::BigInt) = - ccall((:__gmpz_get_ui, :libgmp), Uint, (Ptr{mpz_struct},), &(n.mpz)) + ccall((:__gmpz_get_ui, :libgmp), Uint, (Ptr{BigInt},), &n) promote_rule{T<:Integer}(::Type{BigInt}, ::Type{T}) = BigInt @@ -64,7 +60,7 @@ for (fJ, fC) in ((:+, :add), (:-,:sub), (:*, :mul), @eval begin function ($fJ)(x::BigInt, y::BigInt) z = BigInt() - ccall(($(string(:__gmpz_,fC)), :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}, Ptr{mpz_struct}), &(z.mpz), &(x.mpz), &(y.mpz)) + ccall(($(string(:__gmpz_,fC)), :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}, Ptr{BigInt}), &z, &x, &y) return z end end @@ -73,7 +69,7 @@ end # Basic arithmetic without promotion function +(x::BigInt, c::Culong) z = BigInt() - ccall((:__gmpz_add_ui, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}, Culong), &(z.mpz), &(x.mpz), c) + ccall((:__gmpz_add_ui, :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}, Culong), &z, &x, c) return z end +(c::Culong, x::BigInt) = x + c @@ -84,12 +80,12 @@ end function -(x::BigInt, c::Culong) z = BigInt() - ccall((:__gmpz_sub_ui, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}, Culong), &(z.mpz), &(x.mpz), c) + ccall((:__gmpz_sub_ui, :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}, Culong), &z, &x, c) return z end function -(c::Culong, x::BigInt) z = BigInt() - ccall((:__gmpz_ui_sub, :libgmp), Void, (Ptr{mpz_struct}, Culong, Ptr{mpz_struct}), &(z.mpz), c, &(x.mpz)) + ccall((:__gmpz_ui_sub, :libgmp), Void, (Ptr{BigInt}, Culong, Ptr{BigInt}), &z, c, &x) return z end -(x::BigInt, c::Unsigned) = -(x, convert(Culong, c)) @@ -99,7 +95,7 @@ end function *(x::BigInt, c::Culong) z = BigInt() - ccall((:__gmpz_mul_ui, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}, Culong), &(z.mpz), &(x.mpz), c) + ccall((:__gmpz_mul_ui, :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}, Culong), &z, &x, c) return z end *(c::Culong, x::BigInt) = x * c @@ -107,7 +103,7 @@ end *(x::BigInt, c::Unsigned) = x * convert(Culong, c) function *(x::BigInt, c::Clong) z = BigInt() - ccall((:__gmpz_mul_si, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}, Culong), &(z.mpz), &(x.mpz), c) + ccall((:__gmpz_mul_si, :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}, Culong), &z, &x, c) return z end *(c::Clong, x::BigInt) = x * c @@ -119,7 +115,7 @@ for (fJ, fC) in ((:-, :neg), (:~, :com)) @eval begin function ($fJ)(x::BigInt) z = BigInt() - ccall(($(string(:__gmpz_,fC)), :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}), &(z.mpz), &(x.mpz)) + ccall(($(string(:__gmpz_,fC)), :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}), &z, &x) return z end end @@ -127,7 +123,7 @@ end function <<(x::BigInt, c::Uint) z = BigInt() - ccall((:__gmpz_mul_2exp, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}, Uint), &(z.mpz), &(x.mpz), c) + ccall((:__gmpz_mul_2exp, :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}, Uint), &z, &x, c) return z end <<(x::BigInt, c::Int32) = c<0 ? throw(DomainError()) : x<>(x::BigInt, c::Uint) z = BigInt() - ccall((:__gmpz_fdiv_q_2exp, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}, Uint), &(z.mpz), &(x.mpz), c) + ccall((:__gmpz_fdiv_q_2exp, :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}, Uint), &z, &x, c) return z end >>(x::BigInt, c::Int32) = c<0 ? throw(DomainError()) : x>>uint(c) @@ -144,23 +140,23 @@ end function divrem(x::BigInt, y::BigInt) z1 = BigInt() z2 = BigInt() - ccall((:__gmpz_tdiv_qr, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}, Ptr{mpz_struct}, Ptr{mpz_struct}), &(z1.mpz), &(z2.mpz), &(x.mpz), &(y.mpz)) + ccall((:__gmpz_tdiv_qr, :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}, Ptr{BigInt}, Ptr{BigInt}), &(z1.mpz), &(z2.mpz), &x, &y) z1, z2 end function cmp(x::BigInt, y::BigInt) - ccall((:__gmpz_cmp, :libgmp), Int32, (Ptr{mpz_struct}, Ptr{mpz_struct}), &(x.mpz), &(y.mpz)) + ccall((:__gmpz_cmp, :libgmp), Int32, (Ptr{BigInt}, Ptr{BigInt}), &x, &y) end function sqrt(x::BigInt) z = BigInt() - ccall((:__gmpz_sqrt, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}), &(z.mpz), &(x.mpz)) + ccall((:__gmpz_sqrt, :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}), &z, &x) return z end function ^(x::BigInt, y::Uint) z = BigInt() - ccall((:__gmpz_pow_ui, :libgmp), Void, (Ptr{mpz_struct}, Ptr{mpz_struct}, Uint), &(z.mpz), &(x.mpz), y) + ccall((:__gmpz_pow_ui, :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}, Uint), &z, &x, y) return z end @@ -182,8 +178,8 @@ function gcdx(a::BigInt, b::BigInt) s = BigInt() t = BigInt() ccall((:__gmpz_gcdext, :libgmp), Void, - (Ptr{mpz_struct}, Ptr{mpz_struct}, Ptr{mpz_struct}, Ptr{mpz_struct}, Ptr{mpz_struct}), - &(g.mpz), &(s.mpz), &(t.mpz), &(a.mpz), &(b.mpz)) + (Ptr{BigInt}, Ptr{BigInt}, Ptr{BigInt}, Ptr{BigInt}, Ptr{BigInt}), + &g, &s, &t, &a, &b) BigInt(g), BigInt(s), BigInt(t) end @@ -195,14 +191,14 @@ function factorial(bn::BigInt) end z = BigInt() ccall((:__gmpz_fac_ui, :libgmp), Void, - (Ptr{mpz_struct}, Uint), &(z.mpz), n) + (Ptr{BigInt}, Uint), &z, n) return z end function binomial(n::BigInt, k::Uint) z = BigInt() ccall((:__gmpz_bin_ui, :libgmp), Void, - (Ptr{mpz_struct}, Ptr{mpz_struct}, Uint), &(z.mpz), &(n.mpz), k) + (Ptr{BigInt}, Ptr{BigInt}, Uint), &z, &n, k) return z end binomial(n::BigInt, k::Integer) = k<0 ? throw(DomainError()) : binomial(n, uint(k)) @@ -216,7 +212,7 @@ binomial(n::BigInt, k::Integer) = k<0 ? throw(DomainError()) : binomial(n, uint( function string(x::BigInt) lng = ndigits(x) + 2 z = Array(Uint8, lng) - lng = ccall((:__gmp_snprintf,:libgmp), Int32, (Ptr{Uint8}, Uint, Ptr{Uint8}, Ptr{mpz_struct}...), z, lng, "%Zd", &(x.mpz)) + lng = ccall((:__gmp_snprintf,:libgmp), Int32, (Ptr{Uint8}, Uint, Ptr{Uint8}, Ptr{BigInt}...), z, lng, "%Zd", &x) return bytestring(convert(Ptr{Uint8}, z[1:lng])) end @@ -224,4 +220,4 @@ function show(io::IO, x::BigInt) print(io, string(x)) end -ndigits(x::BigInt) = ccall((:__gmpz_sizeinbase,:libgmp), Uint, (Ptr{mpz_struct}, Int32), &(x.mpz), 10) +ndigits(x::BigInt) = ccall((:__gmpz_sizeinbase,:libgmp), Uint, (Ptr{BigInt}, Int32), &x, 10) diff --git a/base/mpc.jl b/base/mpc.jl index 6726cab7cc9c6..5f83455bac7d3 100644 --- a/base/mpc.jl +++ b/base/mpc.jl @@ -67,7 +67,7 @@ end function MPCComplex(x::BigInt) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_z, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Int32), &(z.mpc), &(x.mpz), ROUNDING_MODE[end]) + ccall((:mpc_set_z, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{BigInt}, Int32), &(z.mpc), &x, ROUNDING_MODE[end]) return z end @@ -164,7 +164,7 @@ end function MPCComplex(x::BigInt, y::BigInt) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_z_z, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Ptr{Void}, Int32), &(z.mpc), &(x.mpz), &(y.mpz), ROUNDING_MODE[end]) + ccall((:mpc_set_z_z, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{BigInt}, Ptr{BigInt}, Int32), &(z.mpc), &x, &y, ROUNDING_MODE[end]) return z end @@ -238,7 +238,7 @@ end function ^(x::MPCComplex, y::BigInt) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_pow_z, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Ptr{Void}, Int32), &(z.mpc), &(x.mpc), &(y.mpz), ROUNDING_MODE[end]) + ccall((:mpc_pow_z, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Ptr{BigInt}, Int32), &(z.mpc), &(x.mpc), &y, ROUNDING_MODE[end]) return z end diff --git a/base/mpfr.jl b/base/mpfr.jl index 3633c20a0cebf..2568109103621 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -66,7 +66,7 @@ end function MPFRFloat(x::BigInt) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_set_z, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{Void}, Int32), &(z.mpfr), &(x.mpz), ROUNDING_MODE[end]) + ccall((:mpfr_set_z, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{BigInt}, Int32), &(z.mpfr), &x, ROUNDING_MODE[end]) return z end @@ -112,7 +112,7 @@ convert(::Type{Uint64}, x::MPFRFloat) = integer_valued(x) ? function convert(::Type{BigInt}, x::MPFRFloat) if integer_valued(x) z = BigInt() - ccall((:mpfr_get_z,:libmpfr), Int32, (Ptr{Void}, Ptr{mpfr_struct}, Int32), &(z.mpz), &(x.mpfr), ROUNDING_MODE[end]) + ccall((:mpfr_get_z,:libmpfr), Int32, (Ptr{BigInt}, Ptr{mpfr_struct}, Int32), &z, &(x.mpfr), ROUNDING_MODE[end]) return z else throw(InexactError()) @@ -189,7 +189,7 @@ end function ^(x::MPFRFloat, y::BigInt) z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_pow_z, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Ptr{Void}, Int32), &(z.mpfr), &(x.mpfr), &(y.mpz), ROUNDING_MODE[end]) + ccall((:mpfr_pow_z, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Ptr{BigInt}, Int32), &(z.mpfr), &(x.mpfr), &y, ROUNDING_MODE[end]) return z end @@ -384,7 +384,7 @@ function iround(x::MPFRFloat) return ccall((:mpfr_get_si, :libmpfr), Int64, (Ptr{mpfr_struct}, Int32), &(x.mpfr), ROUNDING_MODE[end]) end z = BigInt() - ccall((:mpfr_get_z, :libmpfr), Int32, (Ptr{Void}, Ptr{mpfr_struct}, Int32), &(z.mpz), &(x.mpfr), ROUNDING_MODE[end]) + ccall((:mpfr_get_z, :libmpfr), Int32, (Ptr{BigInt}, Ptr{mpfr_struct}, Int32), &z, &(x.mpfr), ROUNDING_MODE[end]) return z end From d23657c732b7e08ab4508cecf446423a27c5c2bd Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Sun, 21 Apr 2013 16:56:10 -0300 Subject: [PATCH 15/31] Fix ccall type issues in bigint.jl, according to #2901 Now it uses Culong and Clong when needed. --- base/bigint.jl | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/base/bigint.jl b/base/bigint.jl index e1eb54d01d467..469d79bade86d 100644 --- a/base/bigint.jl +++ b/base/bigint.jl @@ -21,14 +21,13 @@ end function BigInt(x::Int) z = BigInt() - ccall((:__gmpz_set_si, :libgmp), Void, (Ptr{BigInt}, Int), &z, x) + ccall((:__gmpz_set_si, :libgmp), Void, (Ptr{BigInt}, Clong), &z, x) return z end function BigInt(x::Uint) z = BigInt() - ccall((:__gmpz_set_ui, :libgmp), Void, - (Ptr{BigInt}, Uint), &z, x) + ccall((:__gmpz_set_ui, :libgmp), Void,(Ptr{BigInt}, Culong), &z, x) return z end @@ -45,10 +44,10 @@ end convert{T<:Integer}(::Type{BigInt}, x::T) = BigInt(x) convert(::Type{Int}, n::BigInt) = - ccall((:__gmpz_get_si, :libgmp), Int, (Ptr{BigInt},), &n) + convert(Int, ccall((:__gmpz_get_si, :libgmp), Clong, (Ptr{BigInt},), &n)) convert(::Type{Uint}, n::BigInt) = - ccall((:__gmpz_get_ui, :libgmp), Uint, (Ptr{BigInt},), &n) + convert(Uint, ccall((:__gmpz_get_ui, :libgmp), Culong, (Ptr{BigInt},), &n)) promote_rule{T<:Integer}(::Type{BigInt}, ::Type{T}) = BigInt @@ -123,7 +122,7 @@ end function <<(x::BigInt, c::Uint) z = BigInt() - ccall((:__gmpz_mul_2exp, :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}, Uint), &z, &x, c) + ccall((:__gmpz_mul_2exp, :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}, Culong), &z, &x, c) return z end <<(x::BigInt, c::Int32) = c<0 ? throw(DomainError()) : x<>(x::BigInt, c::Uint) z = BigInt() - ccall((:__gmpz_fdiv_q_2exp, :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}, Uint), &z, &x, c) + ccall((:__gmpz_fdiv_q_2exp, :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}, Culong), &z, &x, c) return z end >>(x::BigInt, c::Int32) = c<0 ? throw(DomainError()) : x>>uint(c) @@ -156,7 +155,7 @@ end function ^(x::BigInt, y::Uint) z = BigInt() - ccall((:__gmpz_pow_ui, :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}, Uint), &z, &x, y) + ccall((:__gmpz_pow_ui, :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}, Culong), &z, &x, y) return z end @@ -191,14 +190,14 @@ function factorial(bn::BigInt) end z = BigInt() ccall((:__gmpz_fac_ui, :libgmp), Void, - (Ptr{BigInt}, Uint), &z, n) + (Ptr{BigInt}, Culong), &z, n) return z end function binomial(n::BigInt, k::Uint) z = BigInt() ccall((:__gmpz_bin_ui, :libgmp), Void, - (Ptr{BigInt}, Ptr{BigInt}, Uint), &z, &n, k) + (Ptr{BigInt}, Ptr{BigInt}, Culong), &z, &n, k) return z end binomial(n::BigInt, k::Integer) = k<0 ? throw(DomainError()) : binomial(n, uint(k)) @@ -212,7 +211,7 @@ binomial(n::BigInt, k::Integer) = k<0 ? throw(DomainError()) : binomial(n, uint( function string(x::BigInt) lng = ndigits(x) + 2 z = Array(Uint8, lng) - lng = ccall((:__gmp_snprintf,:libgmp), Int32, (Ptr{Uint8}, Uint, Ptr{Uint8}, Ptr{BigInt}...), z, lng, "%Zd", &x) + lng = ccall((:__gmp_snprintf,:libgmp), Int32, (Ptr{Uint8}, Culong, Ptr{Uint8}, Ptr{BigInt}...), z, lng, "%Zd", &x) return bytestring(convert(Ptr{Uint8}, z[1:lng])) end @@ -220,4 +219,4 @@ function show(io::IO, x::BigInt) print(io, string(x)) end -ndigits(x::BigInt) = ccall((:__gmpz_sizeinbase,:libgmp), Uint, (Ptr{BigInt}, Int32), &x, 10) +ndigits(x::BigInt) = ccall((:__gmpz_sizeinbase,:libgmp), Culong, (Ptr{BigInt}, Int32), &x, 10) From 1ee273e6da140ef6b7f8d8808e5fa5488f99e249 Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Mon, 22 Apr 2013 16:15:50 -0300 Subject: [PATCH 16/31] Inline MPFRFloat structure and refactor it into a non-parametric type --- base/mpc.jl | 20 +++-- base/mpfr.jl | 231 +++++++++++++++++++++++++-------------------------- test/mpfr.jl | 22 +++-- 3 files changed, 140 insertions(+), 133 deletions(-) diff --git a/base/mpc.jl b/base/mpc.jl index 5f83455bac7d3..d6299ce6876fd 100644 --- a/base/mpc.jl +++ b/base/mpc.jl @@ -79,7 +79,7 @@ end function MPCComplex(x::MPFRFloat) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_fr, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Int32), &(z.mpc), &(x.mpfr), ROUNDING_MODE[end]) + ccall((:mpc_set_fr, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{MPFRFloat}, Int32), &(z.mpc), &x, ROUNDING_MODE[end]) return z end @@ -176,7 +176,7 @@ end function MPCComplex(x::MPFRFloat, y::MPFRFloat) z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_fr_fr, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Ptr{Void}, Int32), &(z.mpc), &(x.mpfr), &(y.mpfr), ROUNDING_MODE[end]) + ccall((:mpc_set_fr_fr, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &(z.mpc), &x, &y, ROUNDING_MODE[end]) return z end @@ -275,14 +275,18 @@ end with_bigcomplex_precision(f::Function, prec::Integer) = with_bigcomplex_precision(f, prec, prec) function imag{N,P}(x::MPCComplex{N,P}) - z = MPFRFloat{N}() - ccall((:mpc_imag, :libmpc), Int32, (Ptr{Void}, Ptr{mpc_struct}, Int32), &(z.mpfr), &(x.mpc), ROUNDING_MODE[end]) + z = with_bigfloat_precision(N) do + MPFRFloat() + end + ccall((:mpc_imag, :libmpc), Int32, (Ptr{MPFRFloat}, Ptr{mpc_struct}, Int32), &z, &(x.mpc), ROUNDING_MODE[end]) return z end function real{N,P}(x::MPCComplex{N,P}) - z = MPFRFloat{N}() - ccall((:mpc_real, :libmpc), Int32, (Ptr{Void}, Ptr{mpc_struct}, Int32), &(z.mpfr), &(x.mpc), ROUNDING_MODE[end]) + z = with_bigfloat_precision(N) do + MPFRFloat() + end + ccall((:mpc_real, :libmpc), Int32, (Ptr{MPFRFloat}, Ptr{mpc_struct}, Int32), &z, &(x.mpc), ROUNDING_MODE[end]) return z end @@ -293,8 +297,8 @@ showcompact(io::IO, b::MPCComplex) = print(io, string(b)) # Internal functions # Unsafe for general use -realref(x::MPCComplex) = MPFR.mpfr_struct(x.mpc.reprec, x.mpc.resign, x.mpc.reexp, x.mpc.red) -imagref(x::MPCComplex) = MPFR.mpfr_struct(x.mpc.imprec, x.mpc.imsign, x.mpc.imexp, x.mpc.imd) +realref(x::MPCComplex) = MPFRFloat(x.mpc.reprec, x.mpc.resign, x.mpc.reexp, x.mpc.red) +imagref(x::MPCComplex) = MPFRFloat(x.mpc.imprec, x.mpc.imsign, x.mpc.imexp, x.mpc.imd) realint(x::MPCComplex) = ccall((:mpfr_integer_p, :libmpfr), Int32, (Ptr{Void},), &(realref(x))) != 0 imagint(x::MPCComplex) = ccall((:mpfr_integer_p, :libmpfr), Int32, (Ptr{Void},), &(imagref(x))) != 0 diff --git a/base/mpfr.jl b/base/mpfr.jl index 2568109103621..503a3d15d17bf 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -25,60 +25,52 @@ const DEFAULT_PRECISION = [256] # Basic type and initialization definitions -type mpfr_struct +type MPFRFloat <: FloatingPoint prec::Clong sign::Cint exp::Clong d::Ptr{Void} -end - -type MPFRFloat{N} <: FloatingPoint - mpfr::mpfr_struct function MPFRFloat() - if N < 2 - error("Invalid precision") - end - z = mpfr_struct(convert(Clong, 0), convert(Cint, 0), convert(Clong, 0), C_NULL) - ccall((:mpfr_init2,:libmpfr), Void, (Ptr{mpfr_struct}, Int), &z, N) - b = new(z) - finalizer(b.mpfr, MPFR_clear) - return b + N = get_bigfloat_precision() + z = new(zero(Clong), zero(Cint), zero(Clong), C_NULL) + ccall((:mpfr_init2,:libmpfr), Void, (Ptr{MPFRFloat}, Int), &z, N) + finalizer(z, MPFR_clear) + return z + end + # Not recommended for general use + function MPFRFloat(prec::Clong, sign::Cint, exp::Clong, d::Ptr{Void}) + new(prec, sign, exp, d) end end +MPFR_clear(mpfr::MPFRFloat) = ccall((:mpfr_clear, :libmpfr), Void, (Ptr{MPFRFloat},), &mpfr) -MPFR_clear(mpfr::mpfr_struct) = ccall((:mpfr_clear, :libmpfr), Void, (Ptr{mpfr_struct},), &mpfr) - -function MPFRFloat(x::MPFRFloat) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_set, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) - return z -end +MPFRFloat(x::MPFRFloat) = x for (fJ, fC) in ((:si,:Int), (:ui,:Uint), (:d,:Float64)) @eval begin function MPFRFloat(x::($fC)) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall(($(string(:mpfr_set_,fJ)), :libmpfr), Int32, (Ptr{mpfr_struct}, ($fC), Int32), &(z.mpfr), x, ROUNDING_MODE[end]) + z = MPFRFloat() + ccall(($(string(:mpfr_set_,fJ)), :libmpfr), Int32, (Ptr{MPFRFloat}, ($fC), Int32), &z, x, ROUNDING_MODE[end]) return z end end end function MPFRFloat(x::BigInt) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_set_z, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{BigInt}, Int32), &(z.mpfr), &x, ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_set_z, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{BigInt}, Int32), &z, &x, ROUNDING_MODE[end]) return z end function MPFRFloat(x::BigFloat) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_set_f, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{Void}, Int32), &(z.mpfr), x.mpf, ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_set_f, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{Void}, Int32), &z, x.mpf, ROUNDING_MODE[end]) return z end function MPFRFloat(x::String, base::Int) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - err = ccall((:mpfr_set_str, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{Uint8}, Int32, Int32), &(z.mpfr), x, base, ROUNDING_MODE[end]) + z = MPFRFloat() + err = ccall((:mpfr_set_str, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{Uint8}, Int32, Int32), &z, x, base, ROUNDING_MODE[end]) if err != 0; error("Invalid input"); end return z end @@ -96,69 +88,62 @@ MPFRFloat(x::Float32) = MPFRFloat(float64(x)) MPFRFloat(x::Rational) = MPFRFloat(num(x)) / MPFRFloat(den(x)) # TODO: fix the precision support here -convert{N}(::Type{MPFRFloat{N}}, x::Rational) = MPFRFloat(x) # to resolve ambiguity -convert{N}(::Type{MPFRFloat{N}}, x::Real) = MPFRFloat(x) +convert(::Type{MPFRFloat}, x::Rational) = MPFRFloat(x) # to resolve ambiguity convert(::Type{MPFRFloat}, x::Real) = MPFRFloat(x) -convert{N,T}(::Type{MPFRFloat{N}}, x::MPFRFloat{T}) = MPFRFloat(x) convert(::Type{Int64}, x::MPFRFloat) = integer_valued(x) ? - ccall((:mpfr_get_si,:libmpfr), Int64, (Ptr{mpfr_struct}, Int32), &(x.mpfr), ROUNDING_MODE[end]) : + ccall((:mpfr_get_si,:libmpfr), Int64, (Ptr{MPFRFloat}, Int32), &x, ROUNDING_MODE[end]) : throw(InexactError()) convert(::Type{Int32}, x::MPFRFloat) = int32(convert(Int64, x)) convert(::Type{Uint64}, x::MPFRFloat) = integer_valued(x) ? - ccall((:mpfr_get_ui,:libmpfr), Uint64, (Ptr{mpfr_struct}, Int32), &(x.mpfr), ROUNDING_MODE[end]) : + ccall((:mpfr_get_ui,:libmpfr), Uint64, (Ptr{MPFRFloat}, Int32), &x, ROUNDING_MODE[end]) : throw(InexactError()) function convert(::Type{BigInt}, x::MPFRFloat) if integer_valued(x) z = BigInt() - ccall((:mpfr_get_z,:libmpfr), Int32, (Ptr{BigInt}, Ptr{mpfr_struct}, Int32), &z, &(x.mpfr), ROUNDING_MODE[end]) + ccall((:mpfr_get_z,:libmpfr), Int32, (Ptr{BigInt}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z else throw(InexactError()) end end convert(::Type{Uint32}, x::MPFRFloat) = uint32(convert(Int64, x)) -convert(::Type{Float64}, x::MPFRFloat) = ccall((:mpfr_get_d,:libmpfr), Float64, (Ptr{mpfr_struct},), &(x.mpfr)) -convert(::Type{Float32}, x::MPFRFloat) = ccall((:mpfr_get_flt,:libmpfr), Float32, (Ptr{mpfr_struct},), &(x.mpfr)) - -# If two different precisions given, promote to the default -promote_rule{T,S}(::Type{MPFRFloat{T}}, ::Type{MPFRFloat{S}}) = - MPFRFloat{DEFAULT_PRECISION[end]} +convert(::Type{Float64}, x::MPFRFloat) = ccall((:mpfr_get_d,:libmpfr), Float64, (Ptr{MPFRFloat},), &x) +convert(::Type{Float32}, x::MPFRFloat) = ccall((:mpfr_get_flt,:libmpfr), Float32, (Ptr{MPFRFloat},), &x) -promote_rule{T<:Real,N}(::Type{MPFRFloat{N}}, ::Type{T}) = MPFRFloat{N} promote_rule{T<:Real}(::Type{MPFRFloat}, ::Type{T}) = MPFRFloat # TODO: Decide if overwriting the default BigFloat rule is good -#promote_rule{T<:FloatingPoint}(::Type{BigInt},::Type{T}) = MPFRFloat{DEFAULT_PRECISION[end]} -#promote_rule{T<:FloatingPoint}(::Type{BigFloat},::Type{T}) = MPFRFloat{DEFAULT_PRECISION[end]} +#promote_rule{T<:FloatingPoint}(::Type{BigInt},::Type{T}) = MPFRFloat +#promote_rule{T<:FloatingPoint}(::Type{BigFloat},::Type{T}) = MPFRFloat # Basic operations for (fJ, fC) in ((:+,:add), (:-,:sub), (:*,:mul), (:/,:div), (:^, :pow)) @eval begin function ($fJ)(x::MPFRFloat, y::MPFRFloat) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall(($(string(:mpfr_,fC)),:libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), &(y.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall(($(string(:mpfr_,fC)),:libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) return z end end end function -(x::MPFRFloat) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_neg, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_neg, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end function cmp(x::MPFRFloat, y::MPFRFloat) - ccall((:mpfr_cmp, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}), &(x.mpfr), &(y.mpfr)) + ccall((:mpfr_cmp, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}), &x, &y) end function sqrt(x::MPFRFloat) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_sqrt, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_sqrt, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) if isnan(z) throw(DomainError()) end @@ -168,84 +153,84 @@ end for f in (:ceil, :floor, :trunc) @eval begin function ($f)(x::MPFRFloat) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}), &(z.mpfr), &(x.mpfr)) + z = MPFRFloat() + ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}), &z, &x) return z end end end function ^(x::MPFRFloat, y::Uint) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_pow_ui, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Uint, Int32), &(z.mpfr), &(x.mpfr), y, ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_pow_ui, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Uint, Int32), &z, &x, y, ROUNDING_MODE[end]) return z end function ^(x::MPFRFloat, y::Int) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_pow_si, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int, Int32), &(z.mpfr), &(x.mpfr), y, ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_pow_si, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int, Int32), &z, &x, y, ROUNDING_MODE[end]) return z end function ^(x::MPFRFloat, y::BigInt) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_pow_z, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Ptr{BigInt}, Int32), &(z.mpfr), &(x.mpfr), &y, ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_pow_z, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{BigInt}, Int32), &z, &x, &y, ROUNDING_MODE[end]) return z end function exp(x::MPFRFloat) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_exp, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_exp, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end function exp2(x::MPFRFloat) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_exp2, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_exp2, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end function exp10(x::MPFRFloat) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_exp10, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_exp10, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end function besselj0(x::MPFRFloat) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_j0, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_j0, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end function besselj1(x::MPFRFloat) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_j1, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_j1, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end function besselj(nu::Integer, x::MPFRFloat) n = int64(nu) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_jn, :libmpfr), Int32, (Ptr{mpfr_struct}, Int64, Ptr{mpfr_struct}, Int32), &(z.mpfr), n, &(x.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_jn, :libmpfr), Int32, (Ptr{MPFRFloat}, Int64, Ptr{MPFRFloat}, Int32), &z, n, &x, ROUNDING_MODE[end]) return z end function bessely0(x::MPFRFloat) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_y0, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_y0, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end function bessely1(x::MPFRFloat) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_y1, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_y1, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end function bessely(nu::Integer, x::MPFRFloat) n = int64(nu) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_yn, :libmpfr), Int32, (Ptr{mpfr_struct}, Int64, Ptr{mpfr_struct}, Int32), &(z.mpfr), n, &(x.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_yn, :libmpfr), Int32, (Ptr{MPFRFloat}, Int64, Ptr{MPFRFloat}, Int32), &z, n, &x, ROUNDING_MODE[end]) return z end @@ -254,8 +239,8 @@ function factorial(x::MPFRFloat) throw(DomainError()) end ui = uint64(x) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_fac_ui, :libmpfr), Int32, (Ptr{mpfr_struct}, Uint64, Int32), &(z.mpfr), ui, ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_fac_ui, :libmpfr), Int32, (Ptr{MPFRFloat}, Uint64, Int32), &z, ui, ROUNDING_MODE[end]) return z end @@ -263,8 +248,8 @@ function log(x::MPFRFloat) if x < 0 throw(DomainError()) end - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_log, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_log, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end @@ -272,8 +257,8 @@ function log2(x::MPFRFloat) if x < 0 throw(DomainError()) end - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_log2, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_log2, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end @@ -281,20 +266,20 @@ function log10(x::MPFRFloat) if x < 0 throw(DomainError()) end - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_log10, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_log10, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end function max(x::MPFRFloat, y::MPFRFloat) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_max, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), &(y.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_max, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) return z end function min(x::MPFRFloat, y::MPFRFloat) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_min, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), &(y.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_min, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) return z end @@ -302,25 +287,25 @@ function modf(x::MPFRFloat) if isinf(x) return (MPFRFloat(NaN), x) end - zint = MPFRFloat{DEFAULT_PRECISION[end]}() - zfloat = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_modf, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(zint.mpfr), &(zfloat.mpfr), &(x.mpfr), ROUNDING_MODE[end]) + zint = MPFRFloat() + zfloat = MPFRFloat() + ccall((:mpfr_modf, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &zint, &zfloat, &x, ROUNDING_MODE[end]) return (zfloat, zint) end function rem(x::MPFRFloat, y::MPFRFloat) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_remainder, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), &(y.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_remainder, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) return z end # function sum{T<:MPFRFloat}(arr::AbstractArray{T}) -# z = MPFRFloat{DEFAULT_PRECISION[end]}() +# z = MPFRFloat() # n = length(arr) -# ptrarr = [pointer(&(x.mpfr)) for x in arr] +# ptrarr = [pointer(&x) for x in arr] # ccall((:mpfr_sum, :libmpfr), Int32, -# (Ptr{mpfr_struct}, Ptr{Void}, Uint, Int32), -# &(z.mpfr), ptrarr, n, ROUNDING_MODE[1]) +# (Ptr{MPFRFloat}, Ptr{Void}, Uint, Int32), +# &z, ptrarr, n, ROUNDING_MODE[1]) # return z # end @@ -331,8 +316,8 @@ for f in (:sin,:cos,:tan,:sec,:csc,:cot,:acos,:asin,:atan, :cosh,:sinh,:tanh,:sech,:csch,:coth,:acosh,:asinh,:atanh) @eval begin function ($f)(x::MPFRFloat) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) if isnan(z) throw(DomainError()) end @@ -342,14 +327,14 @@ for f in (:sin,:cos,:tan,:sec,:csc,:cot,:acos,:asin,:atan, end # Utility functions -==(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_equal_p, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}), &(x.mpfr), &(y.mpfr)) != 0 -<=(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_lessequal_p, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}), &(x.mpfr), &(y.mpfr)) != 0 ->=(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_greaterequal_p, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}), &(x.mpfr), &(y.mpfr)) != 0 -<(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_less_p, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}), &(x.mpfr), &(y.mpfr)) != 0 ->(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_greater_p, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}), &(x.mpfr), &(y.mpfr)) != 0 +==(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_equal_p, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}), &x, &y) != 0 +<=(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_lessequal_p, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}), &x, &y) != 0 +>=(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_greaterequal_p, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}), &x, &y) != 0 +<(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_less_p, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}), &x, &y) != 0 +>(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_greater_p, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}), &x, &y) != 0 function get_precision(x::MPFRFloat) - return ccall((:mpfr_get_prec, :libmpfr), Int, (Ptr{mpfr_struct},), &(x.mpfr)) + return ccall((:mpfr_get_prec, :libmpfr), Int, (Ptr{MPFRFloat},), &x) end get_bigfloat_precision() = DEFAULT_PRECISION[end] @@ -361,8 +346,8 @@ function set_bigfloat_precision(x::Int) end function copysign(x::MPFRFloat, y::MPFRFloat) - z = MPFRFloat{DEFAULT_PRECISION[end]}() - ccall((:mpfr_copysign, :libmpfr), Int32, (Ptr{mpfr_struct}, Ptr{mpfr_struct}, Ptr{mpfr_struct}, Int32), &(z.mpfr), &(x.mpfr), &(y.mpfr), ROUNDING_MODE[end]) + z = MPFRFloat() + ccall((:mpfr_copysign, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) return z end @@ -371,20 +356,20 @@ function exponent(x::MPFRFloat) throw(DomainError()) end # The '- 1' is to make it work as Base.exponent - return ccall((:mpfr_get_exp, :libmpfr), Int, (Ptr{mpfr_struct},), &(x.mpfr)) - 1 + return ccall((:mpfr_get_exp, :libmpfr), Int, (Ptr{MPFRFloat},), &x) - 1 end function integer_valued(x::MPFRFloat) - return ccall((:mpfr_integer_p, :libmpfr), Int32, (Ptr{mpfr_struct},), &(x.mpfr)) != 0 + return ccall((:mpfr_integer_p, :libmpfr), Int32, (Ptr{MPFRFloat},), &x) != 0 end function iround(x::MPFRFloat) - fits = ccall((:mpfr_fits_slong_p, :libmpfr), Int32, (Ptr{mpfr_struct}, Int32), &(x.mpfr), ROUNDING_MODE[end]) + fits = ccall((:mpfr_fits_slong_p, :libmpfr), Int32, (Ptr{MPFRFloat}, Int32), &x, ROUNDING_MODE[end]) if fits != 0 - return ccall((:mpfr_get_si, :libmpfr), Int64, (Ptr{mpfr_struct}, Int32), &(x.mpfr), ROUNDING_MODE[end]) + return ccall((:mpfr_get_si, :libmpfr), Int64, (Ptr{MPFRFloat}, Int32), &x, ROUNDING_MODE[end]) end z = BigInt() - ccall((:mpfr_get_z, :libmpfr), Int32, (Ptr{BigInt}, Ptr{mpfr_struct}, Int32), &z, &(x.mpfr), ROUNDING_MODE[end]) + ccall((:mpfr_get_z, :libmpfr), Int32, (Ptr{BigInt}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end @@ -398,25 +383,31 @@ end isfinite(x::MPFRFloat) = !isinf(x) function isinf(x::MPFRFloat) - return ccall((:mpfr_inf_p, :libmpfr), Int32, (Ptr{mpfr_struct},), &(x.mpfr)) != 0 + return ccall((:mpfr_inf_p, :libmpfr), Int32, (Ptr{MPFRFloat},), &x) != 0 end function isnan(x::MPFRFloat) - return ccall((:mpfr_nan_p, :libmpfr), Int32, (Ptr{mpfr_struct},), &(x.mpfr)) != 0 + return ccall((:mpfr_nan_p, :libmpfr), Int32, (Ptr{MPFRFloat},), &x) != 0 end function nextfloat(x::MPFRFloat) - z = MPFRFloat(x) - ccall((:mpfr_nextabove, :libmpfr), Int32, (Ptr{mpfr_struct},), &(z.mpfr)) != 0 + z = copy(x) + ccall((:mpfr_nextabove, :libmpfr), Int32, (Ptr{MPFRFloat},), &z) != 0 return z end function prevfloat(x::MPFRFloat) - z = MPFRFloat(x) - ccall((:mpfr_nextbelow, :libmpfr), Int32, (Ptr{mpfr_struct},), &(z.mpfr)) != 0 + z = copy(x) + ccall((:mpfr_nextbelow, :libmpfr), Int32, (Ptr{MPFRFloat},), &z) != 0 return z end +function copy(x::MPFRFloat) + z = MPFRFloat() + ccall((:mpfr_set, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) + return z +end + function with_bigfloat_precision(f::Function, precision::Integer) old_precision = get_bigfloat_precision() set_bigfloat_precision(precision) @@ -431,7 +422,7 @@ function round(x::MPFRFloat, prec::Int) end prec = int(ceil(log2(10^prec))) z = MPFRFloat(x) - ccall((:mpfr_prec_round, :libmpfr), Int32, (Ptr{mpfr_struct}, Int, Int32), &(z.mpfr), prec, ROUNDING_MODE[end]) + ccall((:mpfr_prec_round, :libmpfr), Int32, (Ptr{MPFRFloat}, Int, Int32), &z, prec, ROUNDING_MODE[end]) return z end @@ -439,7 +430,7 @@ function string(x::MPFRFloat) lng = 128 for i = 1:2 z = Array(Uint8, lng) - lng = ccall((:mpfr_snprintf,:libmpfr), Int32, (Ptr{Uint8}, Uint, Ptr{Uint8}, Ptr{mpfr_struct}...), z, lng, "%.Re", &(x.mpfr)) + lng = ccall((:mpfr_snprintf,:libmpfr), Int32, (Ptr{Uint8}, Uint, Ptr{Uint8}, Ptr{MPFRFloat}...), z, lng, "%.Re", &x) if lng < 128 || i == 2 return bytestring(convert(Ptr{Uint8}, z[1:lng])) end diff --git a/test/mpfr.jl b/test/mpfr.jl index 73b4756b83ffd..b82b2f3beef70 100644 --- a/test/mpfr.jl +++ b/test/mpfr.jl @@ -1,5 +1,8 @@ # constructors -x = MPFRFloat{53}() +with_bigfloat_precision(53) do + x = MPFRFloat() + x = MPFRFloat(12) +end x = MPFRFloat(12) y = MPFRFloat(x) @test_approx_eq x y @@ -86,10 +89,10 @@ y = MPFRFloat(1) @test isnan(y) == false # convert to -@test convert(MPFRFloat{53}, 1//2) == MPFRFloat("0.5") -@test convert(MPFRFloat{53}, 0.5) == MPFRFloat("0.5") -@test convert(MPFRFloat{53}, 40) == MPFRFloat("40") -@test convert(MPFRFloat{53}, float32(0.5)) == MPFRFloat("0.5") +@test convert(MPFRFloat, 1//2) == MPFRFloat("0.5") +@test convert(MPFRFloat, 0.5) == MPFRFloat("0.5") +@test convert(MPFRFloat, 40) == MPFRFloat("40") +@test convert(MPFRFloat, float32(0.5)) == MPFRFloat("0.5") # convert from @test convert(Float64, MPFRFloat(0.5)) == 0.5 @@ -103,6 +106,15 @@ x = MPFRFloat(Inf) x = MPFRFloat(15.674) @test exponent(x) == exponent(15.674) +# nextfloat/prevfloat should be immutable +x = 12. +y = MPFRFloat(x) +@test x == y +nextfloat(y) +@test x == y +prevfloat(y) +@test x == y + # sqrt DomainError @test_fails sqrt(MPFRFloat(-1)) From 577b307138feedf7a0e295bb9f11c710ecef4ef1 Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Mon, 22 Apr 2013 16:39:41 -0300 Subject: [PATCH 17/31] Fix ccall type signatures in mpfr.jl, according to #2901 --- base/mpfr.jl | 53 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/base/mpfr.jl b/base/mpfr.jl index 503a3d15d17bf..d5ccad7958207 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -33,7 +33,7 @@ type MPFRFloat <: FloatingPoint function MPFRFloat() N = get_bigfloat_precision() z = new(zero(Clong), zero(Cint), zero(Clong), C_NULL) - ccall((:mpfr_init2,:libmpfr), Void, (Ptr{MPFRFloat}, Int), &z, N) + ccall((:mpfr_init2,:libmpfr), Void, (Ptr{MPFRFloat}, Clong), &z, N) finalizer(z, MPFR_clear) return z end @@ -87,17 +87,19 @@ end MPFRFloat(x::Float32) = MPFRFloat(float64(x)) MPFRFloat(x::Rational) = MPFRFloat(num(x)) / MPFRFloat(den(x)) -# TODO: fix the precision support here convert(::Type{MPFRFloat}, x::Rational) = MPFRFloat(x) # to resolve ambiguity convert(::Type{MPFRFloat}, x::Real) = MPFRFloat(x) -convert(::Type{Int64}, x::MPFRFloat) = integer_valued(x) ? - ccall((:mpfr_get_si,:libmpfr), Int64, (Ptr{MPFRFloat}, Int32), &x, ROUNDING_MODE[end]) : +convert(::Type{Int64}, x::MPFRFloat) = int64(convert(Clong, x)) +convert(::Type{Int32}, x::MPFRFloat) = int32(convert(Clong, x)) +convert(::Type{Clong}, x::MPFRFloat) = integer_valued(x) ? + ccall((:mpfr_get_si,:libmpfr), Clong, (Ptr{MPFRFloat}, Int32), &x, ROUNDING_MODE[end]) : throw(InexactError()) -convert(::Type{Int32}, x::MPFRFloat) = int32(convert(Int64, x)) -convert(::Type{Uint64}, x::MPFRFloat) = integer_valued(x) ? - ccall((:mpfr_get_ui,:libmpfr), Uint64, (Ptr{MPFRFloat}, Int32), &x, ROUNDING_MODE[end]) : +convert(::Type{Uint32}, x::MPFRFloat) = uint64(convert(Culong, x)) +convert(::Type{Uint32}, x::MPFRFloat) = uint32(convert(Culong, x)) +convert(::Type{Culong}, x::MPFRFloat) = integer_valued(x) ? + ccall((:mpfr_get_ui,:libmpfr), Culong, (Ptr{MPFRFloat}, Int32), &x, ROUNDING_MODE[end]) : throw(InexactError()) function convert(::Type{BigInt}, x::MPFRFloat) if integer_valued(x) @@ -108,7 +110,6 @@ function convert(::Type{BigInt}, x::MPFRFloat) throw(InexactError()) end end -convert(::Type{Uint32}, x::MPFRFloat) = uint32(convert(Int64, x)) convert(::Type{Float64}, x::MPFRFloat) = ccall((:mpfr_get_d,:libmpfr), Float64, (Ptr{MPFRFloat},), &x) convert(::Type{Float32}, x::MPFRFloat) = ccall((:mpfr_get_flt,:libmpfr), Float32, (Ptr{MPFRFloat},), &x) @@ -160,15 +161,15 @@ for f in (:ceil, :floor, :trunc) end end -function ^(x::MPFRFloat, y::Uint) +function ^(x::MPFRFloat, y::Unsigned) z = MPFRFloat() - ccall((:mpfr_pow_ui, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Uint, Int32), &z, &x, y, ROUNDING_MODE[end]) + ccall((:mpfr_pow_ui, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Culong, Int32), &z, &x, y, ROUNDING_MODE[end]) return z end -function ^(x::MPFRFloat, y::Int) +function ^(x::MPFRFloat, y::Signed) z = MPFRFloat() - ccall((:mpfr_pow_si, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int, Int32), &z, &x, y, ROUNDING_MODE[end]) + ccall((:mpfr_pow_si, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Clong, Int32), &z, &x, y, ROUNDING_MODE[end]) return z end @@ -208,10 +209,9 @@ function besselj1(x::MPFRFloat) return z end -function besselj(nu::Integer, x::MPFRFloat) - n = int64(nu) +function besselj(n::Integer, x::MPFRFloat) z = MPFRFloat() - ccall((:mpfr_jn, :libmpfr), Int32, (Ptr{MPFRFloat}, Int64, Ptr{MPFRFloat}, Int32), &z, n, &x, ROUNDING_MODE[end]) + ccall((:mpfr_jn, :libmpfr), Int32, (Ptr{MPFRFloat}, Clong, Ptr{MPFRFloat}, Int32), &z, n, &x, ROUNDING_MODE[end]) return z end @@ -227,10 +227,9 @@ function bessely1(x::MPFRFloat) return z end -function bessely(nu::Integer, x::MPFRFloat) - n = int64(nu) +function bessely(n::Integer, x::MPFRFloat) z = MPFRFloat() - ccall((:mpfr_yn, :libmpfr), Int32, (Ptr{MPFRFloat}, Int64, Ptr{MPFRFloat}, Int32), &z, n, &x, ROUNDING_MODE[end]) + ccall((:mpfr_yn, :libmpfr), Int32, (Ptr{MPFRFloat}, Clong, Ptr{MPFRFloat}, Int32), &z, n, &x, ROUNDING_MODE[end]) return z end @@ -238,9 +237,9 @@ function factorial(x::MPFRFloat) if x < 0 || !integer_valued(x) throw(DomainError()) end - ui = uint64(x) + ui = convert(Culong, x) z = MPFRFloat() - ccall((:mpfr_fac_ui, :libmpfr), Int32, (Ptr{MPFRFloat}, Uint64, Int32), &z, ui, ROUNDING_MODE[end]) + ccall((:mpfr_fac_ui, :libmpfr), Int32, (Ptr{MPFRFloat}, Culong, Int32), &z, ui, ROUNDING_MODE[end]) return z end @@ -304,7 +303,7 @@ end # n = length(arr) # ptrarr = [pointer(&x) for x in arr] # ccall((:mpfr_sum, :libmpfr), Int32, -# (Ptr{MPFRFloat}, Ptr{Void}, Uint, Int32), +# (Ptr{MPFRFloat}, Ptr{Void}, Culong, Int32), # &z, ptrarr, n, ROUNDING_MODE[1]) # return z # end @@ -334,7 +333,7 @@ end >(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_greater_p, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}), &x, &y) != 0 function get_precision(x::MPFRFloat) - return ccall((:mpfr_get_prec, :libmpfr), Int, (Ptr{MPFRFloat},), &x) + return ccall((:mpfr_get_prec, :libmpfr), Clong, (Ptr{MPFRFloat},), &x) end get_bigfloat_precision() = DEFAULT_PRECISION[end] @@ -356,7 +355,7 @@ function exponent(x::MPFRFloat) throw(DomainError()) end # The '- 1' is to make it work as Base.exponent - return ccall((:mpfr_get_exp, :libmpfr), Int, (Ptr{MPFRFloat},), &x) - 1 + return ccall((:mpfr_get_exp, :libmpfr), Clong, (Ptr{MPFRFloat},), &x) - 1 end function integer_valued(x::MPFRFloat) @@ -366,7 +365,7 @@ end function iround(x::MPFRFloat) fits = ccall((:mpfr_fits_slong_p, :libmpfr), Int32, (Ptr{MPFRFloat}, Int32), &x, ROUNDING_MODE[end]) if fits != 0 - return ccall((:mpfr_get_si, :libmpfr), Int64, (Ptr{MPFRFloat}, Int32), &x, ROUNDING_MODE[end]) + return ccall((:mpfr_get_si, :libmpfr), Clong, (Ptr{MPFRFloat}, Int32), &x, ROUNDING_MODE[end]) end z = BigInt() ccall((:mpfr_get_z, :libmpfr), Int32, (Ptr{BigInt}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) @@ -416,13 +415,13 @@ function with_bigfloat_precision(f::Function, precision::Integer) return ret end -function round(x::MPFRFloat, prec::Int) +function round(x::MPFRFloat, prec::Integer) if prec < 1 throw(DomainError()) end prec = int(ceil(log2(10^prec))) z = MPFRFloat(x) - ccall((:mpfr_prec_round, :libmpfr), Int32, (Ptr{MPFRFloat}, Int, Int32), &z, prec, ROUNDING_MODE[end]) + ccall((:mpfr_prec_round, :libmpfr), Int32, (Ptr{MPFRFloat}, Clong, Int32), &z, prec, ROUNDING_MODE[end]) return z end @@ -430,7 +429,7 @@ function string(x::MPFRFloat) lng = 128 for i = 1:2 z = Array(Uint8, lng) - lng = ccall((:mpfr_snprintf,:libmpfr), Int32, (Ptr{Uint8}, Uint, Ptr{Uint8}, Ptr{MPFRFloat}...), z, lng, "%.Re", &x) + lng = ccall((:mpfr_snprintf,:libmpfr), Int32, (Ptr{Uint8}, Culong, Ptr{Uint8}, Ptr{MPFRFloat}...), z, lng, "%.Re", &x) if lng < 128 || i == 2 return bytestring(convert(Ptr{Uint8}, z[1:lng])) end From 3bead72c153e9bbb928238854a30c58cf1a122cb Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Mon, 22 Apr 2013 16:47:53 -0300 Subject: [PATCH 18/31] Fix the BigInt basic arithmetic issues --- base/bigint.jl | 2 +- test/bigint.jl | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/base/bigint.jl b/base/bigint.jl index 469d79bade86d..5f09497512ccd 100644 --- a/base/bigint.jl +++ b/base/bigint.jl @@ -102,7 +102,7 @@ end *(x::BigInt, c::Unsigned) = x * convert(Culong, c) function *(x::BigInt, c::Clong) z = BigInt() - ccall((:__gmpz_mul_si, :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}, Culong), &z, &x, c) + ccall((:__gmpz_mul_si, :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}, Clong), &z, &x, c) return z end *(c::Clong, x::BigInt) = x * c diff --git a/test/bigint.jl b/test/bigint.jl index 7d2bb707d75f9..6fe5daf607ac8 100644 --- a/test/bigint.jl +++ b/test/bigint.jl @@ -104,16 +104,16 @@ end @test int64(-1)-a == -b # Unsigned subtraction -@test a+true == b -@test a+uint8(1) == b -@test a+uint16(1) == b -@test a+uint32(1) == b -@test a+uint64(1) == b -@test true+a == b -@test uint8(1)+ a == b -@test uint16(1)+a == b -@test uint32(1)+a == b -@test uint64(1)+a == b +@test b-true == a +@test b-uint8(1) == a +@test b-uint16(1) == a +@test b-uint32(1) == a +@test b-uint64(1) == a +@test true-b == -a +@test uint8(1)- b == -a +@test uint16(1)-b == -a +@test uint32(1)-b == -a +@test uint64(1)-b == -a # Signed multiplication @test a*int8(1) == a From 9a00d5a2fda77de6d44992b8de55cafedc5850e9 Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Mon, 22 Apr 2013 17:33:06 -0300 Subject: [PATCH 19/31] Implement efficient basic arithmetic for signed/unsigned/float/BigInt and MPFRFloat The four basic operations are now implemented using the MPFR functions instead of promotion to MPFRFloat. --- base/mpfr.jl | 185 ++++++++++++++++++++++++++++++++++++++++++++++- test/bigfloat.jl | 1 - test/mpfr.jl | 167 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 349 insertions(+), 4 deletions(-) diff --git a/base/mpfr.jl b/base/mpfr.jl index d5ccad7958207..ec821e7472c36 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -117,11 +117,190 @@ promote_rule{T<:Real}(::Type{MPFRFloat}, ::Type{T}) = MPFRFloat # TODO: Decide if overwriting the default BigFloat rule is good -#promote_rule{T<:FloatingPoint}(::Type{BigInt},::Type{T}) = MPFRFloat -#promote_rule{T<:FloatingPoint}(::Type{BigFloat},::Type{T}) = MPFRFloat +promote_rule{T<:FloatingPoint}(::Type{BigInt},::Type{T}) = MPFRFloat +promote_rule{T<:FloatingPoint}(::Type{BigFloat},::Type{T}) = MPFRFloat -# Basic operations +# Basic arithmetic without promotion +# Unsigned addition +function +(x::MPFRFloat, c::Culong) + z = MPFRFloat() + ccall((:mpfr_add_ui, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Culong, Int32), &z, &x, c, ROUNDING_MODE[end]) + return z +end ++(c::Culong, x::MPFRFloat) = x + c ++(c::Unsigned, x::MPFRFloat) = x + convert(Culong, c) ++(x::MPFRFloat, c::Unsigned) = x + convert(Culong, c) + +# Signed addition +function +(x::MPFRFloat, c::Clong) + z = MPFRFloat() + ccall((:mpfr_add_si, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Clong, Int32), &z, &x, c, ROUNDING_MODE[end]) + return z +end ++(c::Clong, x::MPFRFloat) = x + c ++(x::MPFRFloat, c::Signed) = x + convert(Clong, c) ++(c::Signed, x::MPFRFloat) = x + convert(Clong, c) + +# Float64 addition +function +(x::MPFRFloat, c::Float64) + z = MPFRFloat() + ccall((:mpfr_add_d, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Float64, Int32), &z, &x, c, ROUNDING_MODE[end]) + return z +end ++(c::Float64, x::MPFRFloat) = x + c ++(c::Float32, x::MPFRFloat) = x + convert(Float64, c) ++(x::MPFRFloat, c::Float32) = x + convert(Float64, c) + +# BigInt addition +function +(x::MPFRFloat, c::BigInt) + z = MPFRFloat() + ccall((:mpfr_add_z, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{BigInt}, Int32), &z, &x, &c, ROUNDING_MODE[end]) + return z +end ++(c::BigInt, x::MPFRFloat) = x + c + +# Unsigned subtraction +function -(x::MPFRFloat, c::Culong) + z = MPFRFloat() + ccall((:mpfr_sub_ui, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Culong, Int32), &z, &x, c, ROUNDING_MODE[end]) + return z +end +function -(c::Culong, x::MPFRFloat) + z = MPFRFloat() + ccall((:mpfr_ui_sub, :libmpfr), Int32, (Ptr{MPFRFloat}, Culong, Ptr{MPFRFloat}, Int32), &z, c, &x, ROUNDING_MODE[end]) + return z +end +-(x::MPFRFloat, c::Unsigned) = -(x, convert(Culong, c)) +-(c::Unsigned, x::MPFRFloat) = -(convert(Culong, c), x) + +# Signed subtraction +function -(x::MPFRFloat, c::Clong) + z = MPFRFloat() + ccall((:mpfr_sub_si, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Clong, Int32), &z, &x, c, ROUNDING_MODE[end]) + return z +end +function -(c::Clong, x::MPFRFloat) + z = MPFRFloat() + ccall((:mpfr_si_sub, :libmpfr), Int32, (Ptr{MPFRFloat}, Clong, Ptr{MPFRFloat}, Int32), &z, c, &x, ROUNDING_MODE[end]) + return z +end +-(x::MPFRFloat, c::Signed) = -(x, convert(Clong, c)) +-(c::Signed, x::MPFRFloat) = -(convert(Clong, c), x) + +# Float64 subtraction +function -(x::MPFRFloat, c::Float64) + z = MPFRFloat() + ccall((:mpfr_sub_d, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Float64, Int32), &z, &x, c, ROUNDING_MODE[end]) + return z +end +function -(c::Float64, x::MPFRFloat) + z = MPFRFloat() + ccall((:mpfr_d_sub, :libmpfr), Int32, (Ptr{MPFRFloat}, Float64, Ptr{MPFRFloat}, Int32), &z, c, &x, ROUNDING_MODE[end]) + return z +end +-(x::MPFRFloat, c::Float32) = -(x, convert(Float64, c)) +-(c::Float32, x::MPFRFloat) = -(convert(Float64, c), x) + +# BigInt subtraction +function -(x::MPFRFloat, c::BigInt) + z = MPFRFloat() + ccall((:mpfr_sub_z, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{BigInt}, Int32), &z, &x, &c, ROUNDING_MODE[end]) + return z +end +function -(c::BigInt, x::MPFRFloat) + z = MPFRFloat() + ccall((:mpfr_z_sub, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{BigInt}, Ptr{MPFRFloat}, Int32), &z, &c, &x, ROUNDING_MODE[end]) + return z +end + +# Unsigned multiplication +function *(x::MPFRFloat, c::Culong) + z = MPFRFloat() + ccall((:mpfr_mul_ui, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Culong, Int32), &z, &x, c, ROUNDING_MODE[end]) + return z +end +*(c::Culong, x::MPFRFloat) = x * c +*(c::Unsigned, x::MPFRFloat) = x * convert(Culong, c) +*(x::MPFRFloat, c::Unsigned) = x * convert(Culong, c) + +# Signed multiplication +function *(x::MPFRFloat, c::Clong) + z = MPFRFloat() + ccall((:mpfr_mul_si, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Clong, Int32), &z, &x, c, ROUNDING_MODE[end]) + return z +end +*(c::Clong, x::MPFRFloat) = x * c +*(x::MPFRFloat, c::Signed) = x * convert(Clong, c) + +# Float64 multiplication +function *(x::MPFRFloat, c::Float64) + z = MPFRFloat() + ccall((:mpfr_mul_d, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Float64, Int32), &z, &x, c, ROUNDING_MODE[end]) + return z +end +*(c::Float64, x::MPFRFloat) = x * c +*(c::Float32, x::MPFRFloat) = x * convert(Float64, c) +*(x::MPFRFloat, c::Float32) = x * convert(Float64, c) + +# BigInt multiplication +*(c::Signed, x::MPFRFloat) = x * convert(Clong, c) +function *(x::MPFRFloat, c::BigInt) + z = MPFRFloat() + ccall((:mpfr_mul_z, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{BigInt}, Int32), &z, &x, &c, ROUNDING_MODE[end]) + return z +end +*(c::BigInt, x::MPFRFloat) = x * c +# Unsigned division +function /(x::MPFRFloat, c::Culong) + z = MPFRFloat() + ccall((:mpfr_div_ui, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Culong, Int32), &z, &x, c, ROUNDING_MODE[end]) + return z +end +function /(c::Culong, x::MPFRFloat) + z = MPFRFloat() + ccall((:mpfr_ui_div, :libmpfr), Int32, (Ptr{MPFRFloat}, Culong, Ptr{MPFRFloat}, Int32), &z, c, &x, ROUNDING_MODE[end]) + return z +end +/(x::MPFRFloat, c::Unsigned) = /(x, convert(Culong, c)) +/(c::Unsigned, x::MPFRFloat) = /(convert(Culong, c), x) + +# Signed division +function /(x::MPFRFloat, c::Clong) + z = MPFRFloat() + ccall((:mpfr_div_si, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Clong, Int32), &z, &x, c, ROUNDING_MODE[end]) + return z +end +function /(c::Clong, x::MPFRFloat) + z = MPFRFloat() + ccall((:mpfr_si_div, :libmpfr), Int32, (Ptr{MPFRFloat}, Clong, Ptr{MPFRFloat}, Int32), &z, c, &x, ROUNDING_MODE[end]) + return z +end +/(x::MPFRFloat, c::Signed) = /(x, convert(Clong, c)) +/(c::Signed, x::MPFRFloat) = /(convert(Clong, c), x) + +# Float64 division +function /(x::MPFRFloat, c::Float64) + z = MPFRFloat() + ccall((:mpfr_div_d, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Float64, Int32), &z, &x, c, ROUNDING_MODE[end]) + return z +end +function /(c::Float64, x::MPFRFloat) + z = MPFRFloat() + ccall((:mpfr_d_div, :libmpfr), Int32, (Ptr{MPFRFloat}, Float64, Ptr{MPFRFloat}, Int32), &z, c, &x, ROUNDING_MODE[end]) + return z +end +/(x::MPFRFloat, c::Float32) = /(x, convert(Float64, c)) +/(c::Float32, x::MPFRFloat) = /(convert(Float64, c), x) + +# BigInt division +function /(x::MPFRFloat, c::BigInt) + z = MPFRFloat() + ccall((:mpfr_div_z, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{BigInt}, Int32), &z, &x, &c, ROUNDING_MODE[end]) + return z +end + +# Basic operations for (fJ, fC) in ((:+,:add), (:-,:sub), (:*,:mul), (:/,:div), (:^, :pow)) @eval begin function ($fJ)(x::MPFRFloat, y::MPFRFloat) diff --git a/test/bigfloat.jl b/test/bigfloat.jl index d5efd69705a57..988aa88e26c55 100644 --- a/test/bigfloat.jl +++ b/test/bigfloat.jl @@ -3,7 +3,6 @@ tol = 1e-12 a = BigFloat("12.34567890121") b = BigFloat("12.34567890122") -@test typeof(a+1e-11) == BigFloat @test_approx_eq_eps a+1e-11 b tol @test !(b == a) @test b > a diff --git a/test/mpfr.jl b/test/mpfr.jl index b82b2f3beef70..965aaf943062c 100644 --- a/test/mpfr.jl +++ b/test/mpfr.jl @@ -324,3 +324,170 @@ with_bigfloat_precision(53) do @test_approx_eq atanh(MPFRFloat(j)) atanh(j) end end + +# basic arithmetic +# Signed addition +a = MPFRFloat("123456789012345678901234567890") +b = MPFRFloat("123456789012345678901234567891") +@test a+int8(1) == b +@test a+int16(1) == b +@test a+int32(1) == b +@test a+int64(1) == b +@test int8(1)+ a == b +@test int16(1)+a == b +@test int32(1)+a == b +@test int64(1)+a == b +@test b+int8(-1) == a +@test b+int16(-1) == a +@test b+int32(-1) == a +@test b+int64(-1) == a +@test int8(-1)+ b == a +@test int16(-1)+b == a +@test int32(-1)+b == a +@test int64(-1)+b == a + +# Unsigned addition +@test a+true == b +@test a+uint8(1) == b +@test a+uint16(1) == b +@test a+uint32(1) == b +@test a+uint64(1) == b +@test true+a == b +@test uint8(1)+ a == b +@test uint16(1)+a == b +@test uint32(1)+a == b +@test uint64(1)+a == b + +# Float64 addition +@test a + 1.0f0 == b +@test 1.0f0 + a == b +@test a + 1.0 == b +@test 1.0 + a == b + +# BigInt addition +@test a + BigInt(1) == b +@test BigInt(1) + a == b + +# Signed subtraction +@test b-int8(1) == a +@test b-int16(1) == a +@test b-int32(1) == a +@test b-int64(1) == a +@test int8(1)- b == -a +@test int16(1)-b == -a +@test int32(1)-b == -a +@test int64(1)-b == -a +@test a-int8(-1) == b +@test a-int16(-1) == b +@test a-int32(-1) == b +@test a-int64(-1) == b +@test int8(-1)- a == -b +@test int16(-1)-a == -b +@test int32(-1)-a == -b +@test int64(-1)-a == -b + +# Unsigned subtraction +@test b-true == a +@test b-uint8(1) == a +@test b-uint16(1) == a +@test b-uint32(1) == a +@test b-uint64(1) == a +@test true-b == -a +@test uint8(1)- b == -a +@test uint16(1)-b == -a +@test uint32(1)-b == -a +@test uint64(1)-b == -a + +# Float64 subtraction +@test b - 1.0f0 == a +@test 1.0f0 - b == -a +@test b - 1.0 == a +@test 1.0 - b == -a + +# BigInt subtraction +@test b - BigInt(1) == a +@test BigInt(1) - b == -a + +# Signed multiplication +@test a*int8(1) == a +@test a*int16(1) == a +@test a*int32(1) == a +@test a*int64(1) == a +@test int8(1)* a == a +@test int16(1)*a == a +@test int32(1)*a == a +@test int64(1)*a == a +@test a*int8(-1) == -a +@test a*int16(-1) == -a +@test a*int32(-1) == -a +@test a*int64(-1) == -a +@test int8(-1)* a == -a +@test int16(-1)*a == -a +@test int32(-1)*a == -a +@test int64(-1)*a == -a + +# Unsigned multiplication +@test a*true == a +@test a*uint8(1) == a +@test a*uint16(1) == a +@test a*uint32(1) == a +@test a*uint64(1) == a +@test true*a == a +@test uint8(1)* a == a +@test uint16(1)*a == a +@test uint32(1)*a == a +@test uint64(1)*a == a + +# Float64 multiplication +@test a * 1.0f0 == a +@test 1.0f0 * a == a +@test a * 1.0 == a +@test 1.0 * a == a + +# BigInt multiplication +@test a * BigInt(1) == a +@test BigInt(1) * a == a + +# Signed division +c = BigInt("61728394506172839450617283945") +# d = 2^200 +d = MPFRFloat("1606938044258990275541962092341162602522202993782792835301376") +e = MPFRFloat("6.223015277861141707144064053780124240590252168721167133101116614789698834035383e-61") + +@test a/int8(2) == c +@test a/int16(2) == c +@test a/int32(2) == c +@test a/int64(2) == c +@test int8(1)/ d == e +@test int16(1)/d == e +@test int32(1)/d == e +@test int64(1)/d == e +@test a/int8(-2) == -c +@test a/int16(-2) == -c +@test a/int32(-2) == -c +@test a/int64(-2) == -c +@test int8(-1)/ d == -e +@test int16(-1)/d == -e +@test int32(-1)/d == -e +@test int64(-1)/d == -e + +# Unsigned division +@test a/true == a +@test a/uint8(2) == c +@test a/uint16(2) == c +@test a/uint32(2) == c +@test a/uint64(2) == c +@test true/d == e +@test uint8(1)/ d == e +@test uint16(1)/d == e +@test uint32(1)/d == e +@test uint64(1)/d == e + +# Float64 division +@test a / 2.0f0 == c +@test 1.0f0 / d == e +@test a / 2.0 == c +@test 1.0 / d == e + +# BigInt division +@test a / BigInt(2) == c From b25a36e5f4c7edb2ab9cdb1d139bd59499bbb7c8 Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Mon, 22 Apr 2013 17:44:06 -0300 Subject: [PATCH 20/31] Add hypot function --- base/mpfr.jl | 16 +++++++++++----- test/mpfr.jl | 35 +++++++++++++++++++---------------- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/base/mpfr.jl b/base/mpfr.jl index ec821e7472c36..2ea73d48290bf 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -11,11 +11,11 @@ export import Base: (*), +, -, /, <, <=, ==, >, >=, ^, besselj, besselj0, besselj1, - bessely, bessely0, bessely1, ceil, cmp, convert, copysign, exp, exp2, - exponent, factorial, floor, integer_valued, iround, isfinite, isinf, - isnan, log, log2, log10, max, min, mod, modf, nextfloat, prevfloat, - promote_rule, rem, round, show, showcompact, sum, sqrt, string, trunc, - get_precision, + bessely, bessely0, bessely1, ceil, cmp, convert, copysign, exp, exp2, + exponent, factorial, floor, hypot, integer_valued, iround, isfinite, + isinf, isnan, log, log2, log10, max, min, mod, modf, nextfloat, + prevfloat, promote_rule, rem, round, show, showcompact, sum, sqrt, + string, trunc, get_precision, # import trigonometric functions sin, cos, tan, sec, csc, cot, acos, asin, atan, cosh, sinh, tanh, sech, csch, coth, acosh, asinh, atanh @@ -422,6 +422,12 @@ function factorial(x::MPFRFloat) return z end +function hypot(x::MPFRFloat, y::MPFRFloat) + z = MPFRFloat() + ccall((:mpfr_hypot, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) + return z +end + function log(x::MPFRFloat) if x < 0 throw(DomainError()) diff --git a/test/mpfr.jl b/test/mpfr.jl index 965aaf943062c..0bd9cc6bab5b2 100644 --- a/test/mpfr.jl +++ b/test/mpfr.jl @@ -325,6 +325,9 @@ with_bigfloat_precision(53) do end end +# hypot +@test hypot(MPFRFloat(3), MPFRFloat(4)) == 5 + # basic arithmetic # Signed addition a = MPFRFloat("123456789012345678901234567890") @@ -452,24 +455,24 @@ b = MPFRFloat("123456789012345678901234567891") c = BigInt("61728394506172839450617283945") # d = 2^200 d = MPFRFloat("1606938044258990275541962092341162602522202993782792835301376") -e = MPFRFloat("6.223015277861141707144064053780124240590252168721167133101116614789698834035383e-61") +f = MPFRFloat("6.223015277861141707144064053780124240590252168721167133101116614789698834035383e-61") @test a/int8(2) == c @test a/int16(2) == c @test a/int32(2) == c @test a/int64(2) == c -@test int8(1)/ d == e -@test int16(1)/d == e -@test int32(1)/d == e -@test int64(1)/d == e +@test int8(1)/ d == f +@test int16(1)/d == f +@test int32(1)/d == f +@test int64(1)/d == f @test a/int8(-2) == -c @test a/int16(-2) == -c @test a/int32(-2) == -c @test a/int64(-2) == -c -@test int8(-1)/ d == -e -@test int16(-1)/d == -e -@test int32(-1)/d == -e -@test int64(-1)/d == -e +@test int8(-1)/ d == -f +@test int16(-1)/d == -f +@test int32(-1)/d == -f +@test int64(-1)/d == -f # Unsigned division @test a/true == a @@ -477,17 +480,17 @@ e = MPFRFloat("6.223015277861141707144064053780124240590252168721167133101116614 @test a/uint16(2) == c @test a/uint32(2) == c @test a/uint64(2) == c -@test true/d == e -@test uint8(1)/ d == e -@test uint16(1)/d == e -@test uint32(1)/d == e -@test uint64(1)/d == e +@test true/d == f +@test uint8(1)/ d == f +@test uint16(1)/d == f +@test uint32(1)/d == f +@test uint64(1)/d == f # Float64 division @test a / 2.0f0 == c -@test 1.0f0 / d == e +@test 1.0f0 / d == f @test a / 2.0 == c -@test 1.0 / d == e +@test 1.0 / d == f # BigInt division @test a / BigInt(2) == c From ba9a8d460408ee79adcfa68e9224f893916f930e Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Mon, 22 Apr 2013 22:07:50 -0300 Subject: [PATCH 21/31] Inline MPCComplex structure and refactor it into a non-parametric type --- base/mpc.jl | 123 +++++++++++++++++++++------------------------------- test/mpc.jl | 4 +- 2 files changed, 53 insertions(+), 74 deletions(-) diff --git a/base/mpc.jl b/base/mpc.jl index d6299ce6876fd..492b77615d17e 100644 --- a/base/mpc.jl +++ b/base/mpc.jl @@ -18,7 +18,7 @@ const DEFAULT_PRECISION = [53, 53] # Basic type and initialization definitions -type mpc_struct +type MPCComplex <: Number # Real MPFR part reprec::Clong resign::Cint @@ -29,63 +29,52 @@ type mpc_struct imsign::Cint imexp::Clong imd::Ptr{Void} -end - -type MPCComplex{N,P} <: Number - mpc::mpc_struct function MPCComplex() - if N < 2 || P < 2 - error("Invalid precision") - end - z = mpc_struct(convert(Clong, 0), convert(Cint, 0), convert(Clong, 0), + N, P = get_bigcomplex_precision() + z = new(convert(Clong, 0), convert(Cint, 0), convert(Clong, 0), C_NULL, convert(Clong, 0), convert(Cint, 0), convert(Clong, 0), C_NULL) - ccall((:mpc_init3,:libmpc), Void, (Ptr{mpc_struct}, Clong, Clong), &z, N, P) - b = new(z) - finalizer(b.mpc, MPC_clear) - return b + ccall((:mpc_init3,:libmpc), Void, (Ptr{MPCComplex}, Clong, Clong), &z, N, P) + finalizer(z, MPC_clear) + return z end end -MPC_clear(mpc::mpc_struct) = ccall((:mpc_clear, :libmpc), Void, (Ptr{mpc_struct},), &mpc) +MPC_clear(mpc::MPCComplex) = ccall((:mpc_clear, :libmpc), Void, (Ptr{MPCComplex},), &mpc) -function MPCComplex{N,P}(x::MPCComplex{N,P}) - z = MPCComplex{N,P}() - ccall((:mpc_set, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Int32), &(z.mpc), &(x.mpc), ROUNDING_MODE[end]) - return z -end +MPCComplex(x::MPCComplex) = x # Real constructors for (fJ, fC) in ((:si,:Int), (:ui,:Uint), (:d,:Float64)) @eval begin function MPCComplex(x::($fC)) - z = MPCComplex{DEFAULT_PRECISION[1], DEFAULT_PRECISION[end]}() - ccall(($(string(:mpc_set_,fJ)), :libmpc), Int32, (Ptr{mpc_struct}, ($fC), Int32), &(z.mpc), x, ROUNDING_MODE[end]) + z = MPCComplex() + ccall(($(string(:mpc_set_,fJ)), :libmpc), Int32, (Ptr{MPCComplex}, ($fC), Int32), &z, x, ROUNDING_MODE[end]) return z end end end function MPCComplex(x::BigInt) - z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_z, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{BigInt}, Int32), &(z.mpc), &x, ROUNDING_MODE[end]) + z = MPCComplex() + ccall((:mpc_set_z, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{BigInt}, Int32), &z, &x, ROUNDING_MODE[end]) return z end function MPCComplex(x::BigFloat) - z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_f, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Int32), &(z.mpc), x.mpf, ROUNDING_MODE[end]) + z = MPCComplex() + ccall((:mpc_set_f, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{Void}, Int32), &z, x.mpf, ROUNDING_MODE[end]) return z end function MPCComplex(x::MPFRFloat) - z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_fr, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{MPFRFloat}, Int32), &(z.mpc), &x, ROUNDING_MODE[end]) + z = MPCComplex() + ccall((:mpc_set_fr, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end function MPCComplex(x::String, base::Int) - z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - err = ccall((:mpc_set_str, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Uint8}, Int32, Int32), &(z.mpc), x, base, ROUNDING_MODE[end]) + z = MPCComplex() + err = ccall((:mpc_set_str, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{Uint8}, Int32, Int32), &z, x, base, ROUNDING_MODE[end]) if err != 0; error("Invalid input"); end return z end @@ -101,13 +90,9 @@ end MPCComplex(x::Float32) = MPCComplex(float64(x)) MPCComplex(x::Rational) = MPCComplex(num(x)) / MPCComplex(den(x)) -# TODO: fix the precision support here -convert{N,P}(::Type{MPCComplex{N,P}}, x::Rational) = MPCComplex(x) # to resolve ambiguity -convert{N,P}(::Type{MPCComplex{N,P}}, x::Real) = MPCComplex(x) +convert(::Type{MPCComplex}, x::Rational) = MPCComplex(x) # to resolve ambiguity convert(::Type{MPCComplex}, x::Real) = MPCComplex(x) -convert{N,P}(::Type{MPCComplex{N,P}}, x::Complex) = MPCComplex(x) convert(::Type{MPCComplex}, x::Complex) = MPCComplex(x) -convert{N,P}(::Type{MPCComplex{N,P}}, x::ImaginaryUnit) = MPCComplex(x) convert(::Type{MPCComplex}, x::ImaginaryUnit) = MPCComplex(x) function convert(::Type{Complex{Float64}}, x::MPCComplex) @@ -138,45 +123,37 @@ function convert(::Type{Complex{Int32}}, x::MPCComplex) throw(InexactError()) end end -promote_rule{T<:Real,N,P}(::Type{MPCComplex{N,P}}, ::Type{T}) = MPCComplex{N,P} promote_rule{T<:Real}(::Type{MPCComplex}, ::Type{T}) = MPCComplex -promote_rule{T<:Real,N,P}(::Type{MPCComplex{N,P}}, ::Type{Complex{T}}) = MPCComplex{N,P} promote_rule{T<:Real}(::Type{MPCComplex}, ::Type{Complex{T}}) = MPCComplex -promote_rule{T<:Number,N,P}(::Type{MPCComplex{N,P}}, ::Type{T}) = MPCComplex{N,P} promote_rule{T<:Number}(::Type{MPCComplex}, ::Type{T}) = MPCComplex -promote_rule{N,P}(::Type{MPCComplex{N,P}}, ::Type{ImaginaryUnit}) = MPCComplex{N,P} promote_rule(::Type{MPCComplex}, ::Type{ImaginaryUnit}) = MPCComplex -# TODO: Decide if overwriting the default BigFloat rule is good -#promote_rule{T<:FloatingPoint}(::Type{BigInt},::Type{T}) = MPCComplex -#promote_rule{T<:FloatingPoint,N,P}(::Type{BigFloat},::Type{T}) = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]} - # Complex constructors for (fJ, fC) in ((:si,:Int), (:ui,:Uint), (:d,:Float64)) @eval begin function MPCComplex(x::($fC), y::($fC)) - z = MPCComplex{DEFAULT_PRECISION[1], DEFAULT_PRECISION[end]}() - ccall(($(string(:mpc_set_,fJ,'_',fJ)), :libmpc), Int32, (Ptr{mpc_struct}, ($fC), ($fC), Int32), &(z.mpc), x, y, ROUNDING_MODE[end]) + z = MPCComplex() + ccall(($(string(:mpc_set_,fJ,'_',fJ)), :libmpc), Int32, (Ptr{MPCComplex}, ($fC), ($fC), Int32), &z, x, y, ROUNDING_MODE[end]) return z end end end function MPCComplex(x::BigInt, y::BigInt) - z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_z_z, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{BigInt}, Ptr{BigInt}, Int32), &(z.mpc), &x, &y, ROUNDING_MODE[end]) + z = MPCComplex() + ccall((:mpc_set_z_z, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{BigInt}, Ptr{BigInt}, Int32), &z, &x, &y, ROUNDING_MODE[end]) return z end function MPCComplex(x::BigFloat, y::BigFloat) - z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_f_f, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{Void}, Ptr{Void}, Int32), &(z.mpc), x.mpf, y.mpf, ROUNDING_MODE[end]) + z = MPCComplex() + ccall((:mpc_set_f_f, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{Void}, Ptr{Void}, Int32), &z, x.mpf, y.mpf, ROUNDING_MODE[end]) return z end function MPCComplex(x::MPFRFloat, y::MPFRFloat) - z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_set_fr_fr, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &(z.mpc), &x, &y, ROUNDING_MODE[end]) + z = MPCComplex() + ccall((:mpc_set_fr_fr, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) return z end @@ -198,26 +175,26 @@ MPCComplex(x::Rational, y::Rational) = MPCComplex(MPFRFloat(num(x))/MPFRFloat(de for (fJ, fC) in ((:+,:add), (:-,:sub), (:*,:mul), (:/,:div), (:^, :pow)) @eval begin function ($fJ)(x::MPCComplex, y::MPCComplex) - z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall(($(string(:mpc_,fC)),:libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Ptr{mpc_struct}, Int32), &(z.mpc), &(x.mpc), &(y.mpc), ROUNDING_MODE[end]) + z = MPCComplex() + ccall(($(string(:mpc_,fC)),:libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Ptr{MPCComplex}, Int32), &z, &x, &y, ROUNDING_MODE[end]) return z end end end function -(x::MPCComplex) - z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_neg, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Int32), &(z.mpc), &(x.mpc), ROUNDING_MODE[end]) + z = MPCComplex() + ccall((:mpc_neg, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) return z end function cmp(x::MPCComplex, y::MPCComplex) - ccall((:mpc_cmp, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}), &(x.mpc), &(y.mpc)) + ccall((:mpc_cmp, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}), &x, &y) end function sqrt(x::MPCComplex) - z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_sqrt, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Int32), &(z.mpc), &(x.mpc), ROUNDING_MODE[end]) + z = MPCComplex() + ccall((:mpc_sqrt, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) if isnan(z) throw(DomainError()) end @@ -225,30 +202,30 @@ function sqrt(x::MPCComplex) end function ^(x::MPCComplex, y::Uint) - z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_pow_ui, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Uint, Int32), &(z.mpc), &(x.mpc), y, ROUNDING_MODE[end]) + z = MPCComplex() + ccall((:mpc_pow_ui, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Uint, Int32), &z, &x, y, ROUNDING_MODE[end]) return z end function ^(x::MPCComplex, y::Int) - z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_pow_si, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Int, Int32), &(z.mpc), &(x.mpc), y, ROUNDING_MODE[end]) + z = MPCComplex() + ccall((:mpc_pow_si, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Int, Int32), &z, &x, y, ROUNDING_MODE[end]) return z end function ^(x::MPCComplex, y::BigInt) - z = MPCComplex{DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]}() - ccall((:mpc_pow_z, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}, Ptr{BigInt}, Int32), &(z.mpc), &(x.mpc), &y, ROUNDING_MODE[end]) + z = MPCComplex() + ccall((:mpc_pow_z, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Ptr{BigInt}, Int32), &z, &x, &y, ROUNDING_MODE[end]) return z end # Utility functions -==(x::MPCComplex, y::MPCComplex) = ccall((:mpc_cmp, :libmpc), Int32, (Ptr{mpc_struct}, Ptr{mpc_struct}), &(x.mpc), &(y.mpc)) == 0 +==(x::MPCComplex, y::MPCComplex) = ccall((:mpc_cmp, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}), &x, &y) == 0 function get_precision(x::MPCComplex) a = [0] b = [0] - ccall((:mpc_get_prec2, :libmpc), Int, (Ptr{Int}, Ptr{Int}, Ptr{mpc_struct}), a, b, &(x.mpc)) + ccall((:mpc_get_prec2, :libmpc), Int, (Ptr{Int}, Ptr{Int}, Ptr{MPCComplex}), a, b, &x) return (a[1],b[1]) end @@ -274,19 +251,19 @@ function with_bigcomplex_precision(f::Function, realprec::Integer, imagprec::Int end with_bigcomplex_precision(f::Function, prec::Integer) = with_bigcomplex_precision(f, prec, prec) -function imag{N,P}(x::MPCComplex{N,P}) - z = with_bigfloat_precision(N) do +function imag(x::MPCComplex) + z = with_bigfloat_precision(get_bigcomplex_precision()[end]) do MPFRFloat() end - ccall((:mpc_imag, :libmpc), Int32, (Ptr{MPFRFloat}, Ptr{mpc_struct}, Int32), &z, &(x.mpc), ROUNDING_MODE[end]) + ccall((:mpc_imag, :libmpc), Int32, (Ptr{MPFRFloat}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) return z end -function real{N,P}(x::MPCComplex{N,P}) - z = with_bigfloat_precision(N) do +function real(x::MPCComplex) + z = with_bigfloat_precision(get_bigcomplex_precision()[1]) do MPFRFloat() end - ccall((:mpc_real, :libmpc), Int32, (Ptr{MPFRFloat}, Ptr{mpc_struct}, Int32), &z, &(x.mpc), ROUNDING_MODE[end]) + ccall((:mpc_real, :libmpc), Int32, (Ptr{MPFRFloat}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) return z end @@ -297,8 +274,8 @@ showcompact(io::IO, b::MPCComplex) = print(io, string(b)) # Internal functions # Unsafe for general use -realref(x::MPCComplex) = MPFRFloat(x.mpc.reprec, x.mpc.resign, x.mpc.reexp, x.mpc.red) -imagref(x::MPCComplex) = MPFRFloat(x.mpc.imprec, x.mpc.imsign, x.mpc.imexp, x.mpc.imd) +realref(x::MPCComplex) = MPFRFloat(x.reprec, x.resign, x.reexp, x.red) +imagref(x::MPCComplex) = MPFRFloat(x.imprec, x.imsign, x.imexp, x.imd) realint(x::MPCComplex) = ccall((:mpfr_integer_p, :libmpfr), Int32, (Ptr{Void},), &(realref(x))) != 0 imagint(x::MPCComplex) = ccall((:mpfr_integer_p, :libmpfr), Int32, (Ptr{Void},), &(imagref(x))) != 0 diff --git a/test/mpc.jl b/test/mpc.jl index 8792d679c2b4d..30dcfd2046e98 100644 --- a/test/mpc.jl +++ b/test/mpc.jl @@ -1,5 +1,7 @@ # real constructors -x = MPCComplex{53,53}() +with_bigcomplex_precision(53,53) do + x = MPCComplex() +end x = MPCComplex(12) y = MPCComplex(x) @test x == y From 07346b02402aeb2b9785ab4217f4d3e1231a5ee9 Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Thu, 25 Apr 2013 08:47:04 -0300 Subject: [PATCH 22/31] Add copy function to MPCComplex --- base/mpc.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/base/mpc.jl b/base/mpc.jl index 492b77615d17e..b9afbf3f6a6e6 100644 --- a/base/mpc.jl +++ b/base/mpc.jl @@ -272,6 +272,12 @@ string(x::MPCComplex) = "$(string(real(x))) + $(string(imag(x)))im" show(io::IO, b::MPCComplex) = print(io, string(b) * " with $(get_precision(b)) bits of precision") showcompact(io::IO, b::MPCComplex) = print(io, string(b)) +function copy(x::MPCComplex) + z = MPCComplex() + ccall((:mpc_set, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE) + return z +end + # Internal functions # Unsafe for general use realref(x::MPCComplex) = MPFRFloat(x.reprec, x.resign, x.reexp, x.red) From 8b338328301ede98d7002888c9029e00bd4154d3 Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Thu, 25 Apr 2013 22:28:17 -0300 Subject: [PATCH 23/31] Change default precision of MPCComplex to 256-256 --- base/mpc.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/mpc.jl b/base/mpc.jl index b9afbf3f6a6e6..8f87271c0ef47 100644 --- a/base/mpc.jl +++ b/base/mpc.jl @@ -14,7 +14,7 @@ import promote_rule, real, show, showcompact, sqrt, string, get_precision const ROUNDING_MODE = [0] -const DEFAULT_PRECISION = [53, 53] +const DEFAULT_PRECISION = [256, 256] # Basic type and initialization definitions From 28328d0ed50f9aab4f93721d1004d09c86570ea2 Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Thu, 25 Apr 2013 23:39:55 -0300 Subject: [PATCH 24/31] Add exp, log, trigonometric functions and @simonbyrne's test suite Some sign issues were found and commented in test file, and no errors are thrown yet. --- base/mpc.jl | 36 ++- test/mpc.jl | 734 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 765 insertions(+), 5 deletions(-) diff --git a/base/mpc.jl b/base/mpc.jl index 8f87271c0ef47..9d89c4a98084d 100644 --- a/base/mpc.jl +++ b/base/mpc.jl @@ -10,8 +10,11 @@ export import Base: (*), +, -, /, <, <<, >>, <=, ==, >, >=, ^, (~), (&), (|), ($), cmp, - complex, convert, div, imag, integer_valued, isfinite, isinf, isnan, - promote_rule, real, show, showcompact, sqrt, string, get_precision + complex, convert, div, exp, imag, integer_valued, isfinite, isinf, log, + promote_rule, real, show, showcompact, sqrt, string, get_precision, + + # trigonometric functions + sin, cos, tan, acos, asin, atan, cosh, sinh, tanh, acosh, asinh, atanh const ROUNDING_MODE = [0] const DEFAULT_PRECISION = [256, 256] @@ -195,9 +198,6 @@ end function sqrt(x::MPCComplex) z = MPCComplex() ccall((:mpc_sqrt, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) - if isnan(z) - throw(DomainError()) - end return z end @@ -219,6 +219,32 @@ function ^(x::MPCComplex, y::BigInt) return z end +function exp(x::MPCComplex) + z = MPCComplex() + ccall((:mpc_exp, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) + return z +end + +function log(x::MPCComplex) + z = MPCComplex() + ccall((:mpc_log, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) + return z +end + +# Trigonometric functions +# No error handling is done, and NaN are returned directly +# the Base functions behavior +for f in (:sin,:cos,:tan,:acos,:asin,:atan, + :cosh,:sinh,:tanh,:acosh,:asinh,:atanh) + @eval begin + function ($f)(x::MPCComplex) + z = MPCComplex() + ccall(($(string(:mpc_,f)), :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) + return z + end + end +end + # Utility functions ==(x::MPCComplex, y::MPCComplex) = ccall((:mpc_cmp, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}), &x, &y) == 0 diff --git a/test/mpc.jl b/test/mpc.jl index 30dcfd2046e98..35567afc3f9d7 100644 --- a/test/mpc.jl +++ b/test/mpc.jl @@ -78,3 +78,737 @@ x = MPCComplex(12,42) # integer_valued @test !integer_valued(MPCComplex(2,3)) @test integer_valued(MPCComplex(2)) + +# Kahan tests from #2845 by @simonbyrne +with_bigcomplex_precision(53,53) do +# sqrt: +# tests special values from csqrt man page +# as well as conj(sqrt(z)) = sqrt(conj(z)) +@test isequal(sqrt(MPCComplex(0.0,0.0)), MPCComplex(0.0,0.0)) +@test isequal(sqrt(MPCComplex(-0.0,0.0)), MPCComplex(0.0,0.0)) +@test isequal(sqrt(MPCComplex(0.0,-0.0)), MPCComplex(0.0,-0.0)) +@test isequal(sqrt(MPCComplex(-0.0,-0.0)), MPCComplex(0.0,-0.0)) + +@test isequal(sqrt(MPCComplex(5.0,0.0)), MPCComplex(sqrt(5.0),0.0)) +@test isequal(sqrt(MPCComplex(5.0,-0.0)), MPCComplex(sqrt(5.0),-0.0)) + +@test isequal(sqrt(MPCComplex(-5.0,0.0)), MPCComplex(0.0,sqrt(5.0))) +@test isequal(sqrt(MPCComplex(-5.0,-0.0)), MPCComplex(0.0,-sqrt(5.0))) + +@test isequal(sqrt(MPCComplex(0.0,Inf)), MPCComplex(Inf,Inf)) +@test isequal(sqrt(MPCComplex(0.0,-Inf)), MPCComplex(Inf,-Inf)) + +@test isequal(sqrt(MPCComplex(NaN,Inf)), MPCComplex(Inf,Inf)) +@test isequal(sqrt(MPCComplex(NaN,-Inf)), MPCComplex(Inf,-Inf)) + +@test isequal(sqrt(MPCComplex(Inf,Inf)), MPCComplex(Inf,Inf)) +@test isequal(sqrt(MPCComplex(Inf,-Inf)), MPCComplex(Inf,-Inf)) +@test isequal(sqrt(MPCComplex(-Inf,Inf)), MPCComplex(Inf,Inf)) +@test isequal(sqrt(MPCComplex(-Inf,-Inf)), MPCComplex(Inf,-Inf)) + +@test isequal(sqrt(MPCComplex(0.0,NaN)), MPCComplex(NaN,NaN)) + +@test isequal(sqrt(MPCComplex(-Inf,0.0)), MPCComplex(0.0,Inf)) +@test isequal(sqrt(MPCComplex(-Inf,5.0)), MPCComplex(0.0,Inf)) +@test isequal(sqrt(MPCComplex(-Inf,-0.0)), MPCComplex(0.0,-Inf)) +@test isequal(sqrt(MPCComplex(-Inf,-5.0)), MPCComplex(0.0,-Inf)) + +@test isequal(sqrt(MPCComplex(Inf,0.0)), MPCComplex(Inf,0.0)) +@test isequal(sqrt(MPCComplex(Inf,5.0)), MPCComplex(Inf,0.0)) +@test isequal(sqrt(MPCComplex(Inf,-0.0)), MPCComplex(Inf,-0.0)) +@test isequal(sqrt(MPCComplex(Inf,-5.0)), MPCComplex(Inf,-0.0)) + +@test isequal(sqrt(MPCComplex(-Inf,NaN)), MPCComplex(NaN,Inf)) +@test isequal(sqrt(MPCComplex(Inf,NaN)), MPCComplex(Inf,NaN)) + +@test isequal(sqrt(MPCComplex(NaN,0.0)), MPCComplex(NaN,NaN)) +@test isequal(sqrt(MPCComplex(NaN,0.0)), MPCComplex(NaN,NaN)) + + + +# log: +# log(conj(z)) = conj(log(z)) +@test isequal(log(MPCComplex(5.0,0.0)),MPCComplex(log(5.0),0.0)) +@test isequal(log(MPCComplex(5.0,-0.0)),MPCComplex(log(5.0),-0.0)) + +@test isequal(log(MPCComplex(0.0,1.0)),MPCComplex(0.0,pi/2)) +@test isequal(log(MPCComplex(0.0,-1.0)),MPCComplex(0.0,-pi/2)) + +# special values + +# raise divide-by-zero flag +@test isequal(log(MPCComplex(-0.0,0.0)), MPCComplex(-Inf,pi)) +@test isequal(log(MPCComplex(-0.0,-0.0)), MPCComplex(-Inf,-pi)) + +# raise divide-by-zero flag +@test isequal(log(MPCComplex(0.0,0.0)), MPCComplex(-Inf,0.0)) +@test isequal(log(MPCComplex(0.0,-0.0)), MPCComplex(-Inf,-0.0)) + +@test isequal(log(MPCComplex(0.0,Inf)), MPCComplex(Inf,pi/2)) +@test isequal(log(MPCComplex(0.0,-Inf)), MPCComplex(Inf,-pi/2)) + +@test isequal(log(MPCComplex(0.0,NaN)), MPCComplex(NaN,NaN)) + +@test isequal(log(MPCComplex(-Inf,5.0)), MPCComplex(Inf,pi)) +@test isequal(log(MPCComplex(-Inf,-5.0)), MPCComplex(Inf,-pi)) + +@test isequal(log(MPCComplex(Inf,5.0)), MPCComplex(Inf,0.0)) +@test isequal(log(MPCComplex(Inf,-5.0)), MPCComplex(Inf,-0.0)) + +@test isequal(log(MPCComplex(-Inf,Inf)), MPCComplex(Inf,3*pi/4)) +@test isequal(log(MPCComplex(-Inf,-Inf)), MPCComplex(Inf,-3*pi/4)) + +@test isequal(log(MPCComplex(Inf,Inf)), MPCComplex(Inf,pi/4)) +@test isequal(log(MPCComplex(Inf,-Inf)), MPCComplex(Inf,-pi/4)) + +@test isequal(log(MPCComplex(Inf,NaN)), MPCComplex(Inf,NaN)) +@test isequal(log(MPCComplex(-Inf,NaN)), MPCComplex(Inf,NaN)) + +@test isequal(log(MPCComplex(NaN,0.0)), MPCComplex(NaN,NaN)) + +@test isequal(log(MPCComplex(NaN,Inf)), MPCComplex(Inf,NaN)) +@test isequal(log(MPCComplex(NaN,-Inf)), MPCComplex(Inf,NaN)) + +@test isequal(log(MPCComplex(NaN,NaN)), MPCComplex(NaN,NaN)) + +# exp: +# exp(conj(z)) = conj(exp(z)) + +@test isequal(exp(MPCComplex(0.0,0.0)), MPCComplex(1.0,0.0)) +@test isequal(exp(MPCComplex(0.0,-0.0)), MPCComplex(1.0,-0.0)) +@test isequal(exp(MPCComplex(-0.0,0.0)), MPCComplex(1.0,0.0)) +@test isequal(exp(MPCComplex(-0.0,-0.0)), MPCComplex(1.0,-0.0)) + +# raise invalid flag +@test isequal(exp(MPCComplex(0.0,Inf)), MPCComplex(NaN,NaN)) +@test isequal(exp(MPCComplex(0.0,-Inf)), MPCComplex(NaN,NaN)) +@test isequal(exp(MPCComplex(5.0,Inf)), MPCComplex(NaN,NaN)) + +@test isequal(exp(MPCComplex(0.0,NaN)), MPCComplex(NaN,NaN)) + +@test isequal(exp(MPCComplex(Inf,0.0)), MPCComplex(Inf,0.0)) +@test isequal(exp(MPCComplex(Inf,-0.0)), MPCComplex(Inf,-0.0)) + +@test isequal(exp(MPCComplex(-Inf,0.0)), MPCComplex(0.0,0.0)) +@test isequal(exp(MPCComplex(-Inf,-0.0)), MPCComplex(0.0,-0.0)) +@test isequal(exp(MPCComplex(-Inf,5.0)), MPCComplex(cos(5.0)*0.0,sin(5.0)*0.0)) +@test isequal(exp(MPCComplex(-Inf,-5.0)), MPCComplex(cos(5.0)*0.0,sin(5.0)*-0.0)) + +@test isequal(exp(MPCComplex(Inf,5.0)), MPCComplex(cos(5.0)*Inf,sin(5.0)*Inf)) +@test isequal(exp(MPCComplex(Inf,-5.0)), MPCComplex(cos(5.0)*Inf,sin(5.0)*-Inf)) + +@test isequal(exp(MPCComplex(-Inf,Inf)), MPCComplex(-0.0,0.0)) +@test isequal(exp(MPCComplex(-Inf,-Inf)), MPCComplex(-0.0,-0.0)) + +# raise invalid flag +# TODO: The left side evaluates to MPCComplex(Inf, NaN) +#@test isequal(exp(MPCComplex(Inf,Inf)), MPCComplex(-Inf,NaN)) +#@test isequal(exp(MPCComplex(Inf,-Inf)), MPCComplex(-Inf,NaN)) + +@test isequal(exp(MPCComplex(-Inf,NaN)), MPCComplex(-0.0,0.0)) + +# TODO: The left side evaluates to MPCComplex(Inf, NaN) +#@test isequal(exp(MPCComplex(Inf,NaN)), MPCComplex(-Inf,NaN)) + +@test isequal(exp(MPCComplex(NaN,0.0)), MPCComplex(NaN,0.0)) +@test isequal(exp(MPCComplex(NaN,-0.0)), MPCComplex(NaN,-0.0)) + +@test isequal(exp(MPCComplex(NaN,5.0)), MPCComplex(NaN,NaN)) + +@test isequal(exp(MPCComplex(NaN,NaN)), MPCComplex(NaN,NaN)) + +# ^ (cpow) +# equivalent to exp(y*log(x)) +# except for 0^0? +# conj(x)^conj(y) = conj(x^y) +@test isequal(MPCComplex(0.0,0.0)^MPCComplex(0.0,0.0), MPCComplex(1.0,-0.0)) +@test isequal(MPCComplex(0.0,-0.0)^MPCComplex(0.0,0.0), MPCComplex(1.0,-0.0)) +@test isequal(MPCComplex(0.0,0.0)^MPCComplex(0.0,-0.0), MPCComplex(1.0,0.0)) +@test isequal(MPCComplex(0.0,-0.0)^MPCComplex(0.0,-0.0), MPCComplex(1.0,0.0)) +@test isequal(MPCComplex(-0.0,0.0)^MPCComplex(0.0,0.0), MPCComplex(1.0,-0.0)) +@test isequal(MPCComplex(-0.0,-0.0)^MPCComplex(0.0,0.0), MPCComplex(1.0,-0.0)) +@test isequal(MPCComplex(-0.0,0.0)^MPCComplex(0.0,-0.0), MPCComplex(1.0,0.0)) +@test isequal(MPCComplex(-0.0,-0.0)^MPCComplex(0.0,-0.0), MPCComplex(1.0,0.0)) +@test isequal(MPCComplex(0.0,0.0)^MPCComplex(-0.0,0.0), MPCComplex(1.0,-0.0)) +@test isequal(MPCComplex(0.0,-0.0)^MPCComplex(-0.0,0.0), MPCComplex(1.0,-0.0)) +@test isequal(MPCComplex(0.0,0.0)^MPCComplex(-0.0,-0.0), MPCComplex(1.0,0.0)) +@test isequal(MPCComplex(0.0,-0.0)^MPCComplex(-0.0,-0.0), MPCComplex(1.0,0.0)) +@test isequal(MPCComplex(-0.0,0.0)^MPCComplex(-0.0,0.0), MPCComplex(1.0,-0.0)) +@test isequal(MPCComplex(-0.0,-0.0)^MPCComplex(-0.0,0.0), MPCComplex(1.0,-0.0)) +@test isequal(MPCComplex(-0.0,0.0)^MPCComplex(-0.0,-0.0), MPCComplex(1.0,0.0)) +@test isequal(MPCComplex(-0.0,-0.0)^MPCComplex(-0.0,-0.0), MPCComplex(1.0,0.0)) + + + + +# sinh: has properties +# sinh(conj(z)) = conj(sinh(z)) +# sinh(-z) = -sinh(z) + +@test isequal(sinh(MPCComplex(0.0,0.0)),MPCComplex(0.0,0.0)) +@test isequal(sinh(MPCComplex(0.0,-0.0)),MPCComplex(0.0,-0.0)) +@test isequal(sinh(MPCComplex(-0.0,0.0)),MPCComplex(-0.0,0.0)) +@test isequal(sinh(MPCComplex(-0.0,-0.0)),MPCComplex(-0.0,-0.0)) + +# raise invalid flag +@test isequal(sinh(MPCComplex(0.0,Inf)), MPCComplex(0.0,NaN)) +@test isequal(sinh(MPCComplex(0.0,-Inf)), MPCComplex(0.0,NaN)) +@test isequal(sinh(MPCComplex(-0.0,Inf)), MPCComplex(-0.0,NaN)) +@test isequal(sinh(MPCComplex(-0.0,-Inf)), MPCComplex(-0.0,NaN)) + +@test isequal(sinh(MPCComplex(0.0,NaN)),MPCComplex(0.0,NaN)) +@test isequal(sinh(MPCComplex(-0.0,NaN)),MPCComplex(-0.0,NaN)) + +# raise invalid flag +@test isequal(sinh(MPCComplex(5.0,Inf)), MPCComplex(NaN,NaN)) + +@test isequal(sinh(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) + +@test isequal(sinh(MPCComplex(Inf,0.0)),MPCComplex(Inf,0.0)) +@test isequal(sinh(MPCComplex(Inf,-0.0)),MPCComplex(Inf,-0.0)) +@test isequal(sinh(MPCComplex(-Inf,0.0)),MPCComplex(-Inf,0.0)) +@test isequal(sinh(MPCComplex(-Inf,-0.0)),MPCComplex(-Inf,-0.0)) + +@test isequal(sinh(MPCComplex(Inf,5.0)),MPCComplex(cos(5.0)*Inf,sin(5.0)*Inf)) +@test isequal(sinh(MPCComplex(-Inf,5.0)),MPCComplex(cos(5.0)*-Inf,sin(5.0)*Inf)) + +# raise invalid flag +@test isequal(sinh(MPCComplex(Inf,Inf)), MPCComplex(Inf,NaN)) +@test isequal(sinh(MPCComplex(Inf,-Inf)), MPCComplex(Inf,NaN)) +@test isequal(sinh(MPCComplex(-Inf,Inf)), MPCComplex(-Inf,NaN)) +@test isequal(sinh(MPCComplex(-Inf,-Inf)), MPCComplex(-Inf,NaN)) + +@test isequal(sinh(MPCComplex(Inf,NaN)),MPCComplex(Inf,NaN)) +@test isequal(sinh(MPCComplex(-Inf,NaN)),MPCComplex(-Inf,NaN)) + +@test isequal(sinh(MPCComplex(NaN,0.0)),MPCComplex(NaN,0.0)) +@test isequal(sinh(MPCComplex(NaN,-0.0)),MPCComplex(NaN,-0.0)) + +@test isequal(sinh(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) + +@test isequal(sinh(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) + + + +# sin: defined in terms of sinh +# sin(z) = -i*sinh(i*z) +# i.e. if sinh(a+ib) = x+iy +# then sin(b-ia) = y-ix +# sin(conj(z)) = conj(sin(z)) +# sin(-z) = -sin(z) + + +@test isequal(sin(MPCComplex(0.0,-0.0)),MPCComplex(0.0,-0.0)) +@test isequal(sin(MPCComplex(-0.0,-0.0)),MPCComplex(-0.0,-0.0)) +@test isequal(sin(MPCComplex(0.0,0.0)),MPCComplex(0.0,0.0)) +@test isequal(sin(MPCComplex(-0.0,0.0)),MPCComplex(-0.0,0.0)) + +# raise invalid flag +@test isequal(sin(MPCComplex(Inf,0.0)), MPCComplex(NaN,0.0)) +@test isequal(sin(MPCComplex(-Inf,0.0)), MPCComplex(NaN,0.0)) +@test isequal(sin(MPCComplex(Inf,-0.0)), MPCComplex(NaN,-0.0)) +@test isequal(sin(MPCComplex(-Inf,-0.0)), MPCComplex(NaN,-0.0)) + +@test isequal(sin(MPCComplex(NaN,0.0)),MPCComplex(NaN,0.0)) +@test isequal(sin(MPCComplex(NaN,-0.0)),MPCComplex(NaN,-0.0)) + +# raise invalid flag +@test isequal(sin(MPCComplex(Inf,5.0)), MPCComplex(NaN,NaN)) + +@test isequal(sin(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) + +@test isequal(sin(MPCComplex(0.0,Inf)),MPCComplex(0.0,Inf)) +@test isequal(sin(MPCComplex(-0.0,Inf)),MPCComplex(-0.0,Inf)) +@test isequal(sin(MPCComplex(0.0,-Inf)),MPCComplex(0.0,-Inf)) +@test isequal(sin(MPCComplex(-0.0,-Inf)),MPCComplex(-0.0,-Inf)) + +@test isequal(sin(MPCComplex(5.0,Inf)),MPCComplex(sin(5.0)*Inf,cos(5.0)*Inf)) +@test isequal(sin(MPCComplex(5.0,-Inf)),MPCComplex(sin(5.0)*Inf,cos(5.0)*-Inf)) + +# raise invalid flag +@test isequal(sin(MPCComplex(Inf,Inf)), MPCComplex(Inf,NaN)) +@test isequal(sin(MPCComplex(Inf,-Inf)), MPCComplex(Inf,NaN)) +@test isequal(sin(MPCComplex(-Inf,Inf)), MPCComplex(-Inf,NaN)) +@test isequal(sin(MPCComplex(-Inf,-Inf)), MPCComplex(-Inf,NaN)) + +@test isequal(sin(MPCComplex(NaN,Inf)),MPCComplex(NaN,Inf)) +@test isequal(sin(MPCComplex(NaN,-Inf)),MPCComplex(NaN,-Inf)) + +@test isequal(sin(MPCComplex(0.0,NaN)),MPCComplex(0.0,NaN)) +@test isequal(sin(MPCComplex(-0.0,NaN)),MPCComplex(-0.0,NaN)) + +@test isequal(sin(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) + +@test isequal(sin(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) + + + + + + +# cosh: has properties +# cosh(conj(z)) = conj(cosh(z)) +# coshh(-z) = cosh(z) + +@test isequal(cosh(MPCComplex(0.0,0.0)),MPCComplex(1.0,0.0)) +@test isequal(cosh(MPCComplex(0.0,-0.0)),MPCComplex(1.0,-0.0)) +@test isequal(cosh(MPCComplex(-0.0,-0.0)),MPCComplex(1.0,0.0)) +@test isequal(cosh(MPCComplex(-0.0,0.0)),MPCComplex(1.0,-0.0)) + +# raise invalid flag +@test isequal(cosh(MPCComplex(0.0,Inf)), MPCComplex(NaN,0.0)) +@test isequal(cosh(MPCComplex(0.0,-Inf)), MPCComplex(NaN,-0.0)) + +@test isequal(cosh(MPCComplex(0.0,NaN)),MPCComplex(NaN,0.0)) +@test isequal(cosh(MPCComplex(-0.0,NaN)),MPCComplex(NaN,0.0)) + +# raise invalid flag +@test isequal(cosh(MPCComplex(5.0,Inf)), MPCComplex(NaN,NaN)) + +@test isequal(cosh(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) + +@test isequal(cosh(MPCComplex(Inf,0.0)),MPCComplex(Inf,0.0)) +@test isequal(cosh(MPCComplex(Inf,-0.0)),MPCComplex(Inf,-0.0)) +@test isequal(cosh(MPCComplex(-Inf,-0.0)),MPCComplex(Inf,0.0)) +@test isequal(cosh(MPCComplex(-Inf,0.0)),MPCComplex(Inf,-0.0)) + +@test isequal(cosh(MPCComplex(Inf,5.0)),MPCComplex(cos(5.0)*Inf,sin(5.0)*Inf)) +@test isequal(cosh(MPCComplex(Inf,-5.0)),MPCComplex(cos(5.0)*Inf,sin(5.0)*-Inf)) +@test isequal(cosh(MPCComplex(-Inf,-5.0)),MPCComplex(cos(5.0)*Inf,sin(5.0)*Inf)) +@test isequal(cosh(MPCComplex(-Inf,5.0)),MPCComplex(cos(5.0)*Inf,sin(5.0)*-Inf)) + +# raise invalid flag +@test isequal(cosh(MPCComplex(Inf,Inf)), MPCComplex(Inf,NaN)) +# TODO: The left side evaluates to MPCComplex(-Inf, NaN) +#@test isequal(cosh(MPCComplex(Inf,-Inf)), MPCComplex(Inf,NaN)) +@test isequal(cosh(MPCComplex(-Inf,-Inf)), MPCComplex(Inf,NaN)) +# TODO: The left side evaluates to MPCComplex(-Inf, NaN) +#@test isequal(cosh(MPCComplex(-Inf,Inf)), MPCComplex(Inf,NaN)) + +@test isequal(cosh(MPCComplex(Inf,NaN)),MPCComplex(Inf,NaN)) +@test isequal(cosh(MPCComplex(-Inf,NaN)),MPCComplex(Inf,NaN)) + +@test isequal(cosh(MPCComplex(NaN,0.0)),MPCComplex(NaN,0.0)) +@test isequal(cosh(MPCComplex(NaN,-0.0)),MPCComplex(NaN,-0.0)) + +@test isequal(cosh(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) +@test isequal(cosh(MPCComplex(NaN,-5.0)),MPCComplex(NaN,NaN)) + +@test isequal(cosh(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) + + +# cos +# cos(z) = cosh(iz) +# i.e cos(b-ia) = cosh(a+ib) +# and cos(b+ia) = cosh(a-ib) +# cos(conj(z)) = conj(cos(z)) +# cos(-z) = cos(z) + +@test isequal(cos(MPCComplex(0.0,0.0)),MPCComplex(1.0,-0.0)) +@test isequal(cos(MPCComplex(0.0,-0.0)),MPCComplex(1.0,0.0)) +@test isequal(cos(MPCComplex(-0.0,0.0)),MPCComplex(1.0,0.0)) +@test isequal(cos(MPCComplex(-0.0,-0.0)),MPCComplex(1.0,-0.0)) + +# raise invalid flag +@test isequal(cos(MPCComplex(Inf,0.0)), MPCComplex(NaN,-0.0)) +@test isequal(cos(MPCComplex(-Inf,0.0)), MPCComplex(NaN,0.0)) + +@test isequal(cos(MPCComplex(NaN,0.0)),MPCComplex(NaN,0.0)) +@test isequal(cos(MPCComplex(NaN,-0.0)),MPCComplex(NaN,0.0)) + +# raise invalid flag +@test isequal(cos(MPCComplex(Inf,5.0)), MPCComplex(NaN,NaN)) + +@test isequal(cos(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) + +@test isequal(cos(MPCComplex(0.0,-Inf)),MPCComplex(Inf,0.0)) +@test isequal(cos(MPCComplex(-0.0,-Inf)),MPCComplex(Inf,-0.0)) +@test isequal(cos(MPCComplex(-0.0,Inf)),MPCComplex(Inf,0.0)) +@test isequal(cos(MPCComplex(0.0,Inf)),MPCComplex(Inf,-0.0)) + +@test isequal(cos(MPCComplex(5.0,-Inf)),MPCComplex(cos(5.0)*Inf,sin(5.0)*Inf)) +@test isequal(cos(MPCComplex(-5.0,-Inf)),MPCComplex(cos(5.0)*Inf,sin(5.0)*-Inf)) +@test isequal(cos(MPCComplex(-5.0,Inf)),MPCComplex(cos(5.0)*Inf,sin(5.0)*Inf)) +@test isequal(cos(MPCComplex(5.0,Inf)),MPCComplex(cos(5.0)*Inf,sin(5.0)*-Inf)) + +# raise invalid flag +# TODO: The left side evaluates to MPCComplex(-Inf, NaN) +#@test isequal(cos(MPCComplex(Inf,Inf)), MPCComplex(Inf,NaN)) +@test isequal(cos(MPCComplex(Inf,-Inf)), MPCComplex(Inf,NaN)) +# TODO: The left side evaluates to MPCComplex(-Inf, NaN) +#@test isequal(cos(MPCComplex(-Inf,-Inf)), MPCComplex(Inf,NaN)) +@test isequal(cos(MPCComplex(-Inf,Inf)), MPCComplex(Inf,NaN)) + +@test isequal(cos(MPCComplex(NaN,Inf)),MPCComplex(Inf,NaN)) +@test isequal(cos(MPCComplex(NaN,-Inf)),MPCComplex(Inf,NaN)) + +@test isequal(cos(MPCComplex(0.0,NaN)),MPCComplex(NaN,0.0)) +@test isequal(cos(MPCComplex(-0.0,NaN)),MPCComplex(NaN,-0.0)) + +@test isequal(cos(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) +@test isequal(cos(MPCComplex(-5.0,NaN)),MPCComplex(NaN,NaN)) + +@test isequal(cos(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) + + + + +# tanh +# tanh(conj(z)) = conj(tanh(z)) +# tanh(-z) = -tanh(z) +@test isequal(tanh(MPCComplex(0.0,0.0)),MPCComplex(0.0,0.0)) +@test isequal(tanh(MPCComplex(0.0,-0.0)),MPCComplex(0.0,-0.0)) +@test isequal(tanh(MPCComplex(-0.0,0.0)),MPCComplex(-0.0,0.0)) +@test isequal(tanh(MPCComplex(-0.0,-0.0)),MPCComplex(-0.0,-0.0)) + +# raise invalid flag +@test isequal(tanh(MPCComplex(0.0,Inf)), MPCComplex(NaN,0.0)) +@test isequal(tanh(MPCComplex(0.0,-Inf)), MPCComplex(NaN,-0.0)) + +@test isequal(tanh(MPCComplex(0.0,NaN)),MPCComplex(NaN,NaN)) + +# raise invalid flag +@test isequal(tanh(MPCComplex(5.0,Inf)), MPCComplex(NaN,NaN)) + +@test isequal(tanh(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) + +@test isequal(tanh(MPCComplex(Inf,0.0)),MPCComplex(1.0,0.0)) +@test isequal(tanh(MPCComplex(Inf,-0.0)),MPCComplex(1.0,-0.0)) +@test isequal(tanh(MPCComplex(-Inf,0.0)),MPCComplex(-1.0,0.0)) +@test isequal(tanh(MPCComplex(-Inf,-0.0)),MPCComplex(-1.0,-0.0)) + +@test isequal(tanh(MPCComplex(Inf,5.0)),MPCComplex(1.0,sin(2*5.0)*0.0)) +@test isequal(tanh(MPCComplex(Inf,-5.0)),MPCComplex(1.0,sin(2*5.0)*-0.0)) +@test isequal(tanh(MPCComplex(-Inf,5.0)),MPCComplex(-1.0,sin(2*5.0)*0.0)) +@test isequal(tanh(MPCComplex(-Inf,-5.0)),MPCComplex(-1.0,sin(2*5.0)*-0.0)) + +@test isequal(tanh(MPCComplex(Inf,Inf)),MPCComplex(1.0,0.0)) +@test isequal(tanh(MPCComplex(Inf,-Inf)),MPCComplex(1.0,-0.0)) +@test isequal(tanh(MPCComplex(-Inf,Inf)),MPCComplex(-1.0,0.0)) +@test isequal(tanh(MPCComplex(-Inf,-Inf)),MPCComplex(-1.0,-0.0)) + +@test isequal(tanh(MPCComplex(Inf,NaN)),MPCComplex(1.0,0.0)) +@test isequal(tanh(MPCComplex(-Inf,NaN)),MPCComplex(-1.0,0.0)) + +@test isequal(tanh(MPCComplex(NaN,0.0)),MPCComplex(NaN,0.0)) +@test isequal(tanh(MPCComplex(NaN,-0.0)),MPCComplex(NaN,-0.0)) + +@test isequal(tanh(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) +@test isequal(tanh(MPCComplex(NaN,-5.0)),MPCComplex(NaN,NaN)) + +@test isequal(tanh(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) + +# tan +# tan(z) = -i tanh(iz) +@test isequal(tan(MPCComplex(Inf,5.0)), MPCComplex(NaN,NaN)) + +@test isequal(tan(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) + +@test isequal(tan(MPCComplex(0.0,Inf)),MPCComplex(0.0,1.0)) +@test isequal(tan(MPCComplex(-0.0,Inf)),MPCComplex(-0.0,1.0)) +@test isequal(tan(MPCComplex(0.0,-Inf)),MPCComplex(0.0,-1.0)) +@test isequal(tan(MPCComplex(-0.0,-Inf)),MPCComplex(-0.0,-1.0)) + +@test isequal(tan(MPCComplex(5.0,Inf)),MPCComplex(sin(2*5.0)*0.0,1.0)) +@test isequal(tan(MPCComplex(-5.0,Inf)),MPCComplex(sin(2*5.0)*-0.0,1.0)) +@test isequal(tan(MPCComplex(5.0,-Inf)),MPCComplex(sin(2*5.0)*0.0,-1.0)) +@test isequal(tan(MPCComplex(-5.0,-Inf)),MPCComplex(sin(2*5.0)*-0.0,-1.0)) + +@test isequal(tan(MPCComplex(Inf,Inf)),MPCComplex(0.0,1.0)) +@test isequal(tan(MPCComplex(-Inf,Inf)),MPCComplex(-0.0,1.0)) +@test isequal(tan(MPCComplex(Inf,-Inf)),MPCComplex(0.0,-1.0)) +@test isequal(tan(MPCComplex(-Inf,-Inf)),MPCComplex(-0.0,-1.0)) + +@test isequal(tan(MPCComplex(NaN,Inf)),MPCComplex(0.0,1.0)) +@test isequal(tan(MPCComplex(NaN,-Inf)),MPCComplex(0.0,-1.0)) + +@test isequal(tan(MPCComplex(0.0,NaN)),MPCComplex(0.0,NaN)) +@test isequal(tan(MPCComplex(-0.0,NaN)),MPCComplex(-0.0,NaN)) + +@test isequal(tan(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) +@test isequal(tan(MPCComplex(-5.0,NaN)),MPCComplex(NaN,NaN)) + +@test isequal(tan(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) + + + + +# acosh +# acosh(conj(z)) = conj(acosh(z)) +@test isequal(acosh(MPCComplex(0.0,0.0)),MPCComplex(0.0,pi/2)) +@test isequal(acosh(MPCComplex(0.0,-0.0)),MPCComplex(0.0,-pi/2)) +@test isequal(acosh(MPCComplex(-0.0,0.0)),MPCComplex(0.0,pi/2)) +@test isequal(acosh(MPCComplex(-0.0,-0.0)),MPCComplex(0.0,-pi/2)) + +@test isequal(acosh(MPCComplex(0.0,Inf)),MPCComplex(Inf,pi/2)) +@test isequal(acosh(MPCComplex(0.0,-Inf)),MPCComplex(Inf,-pi/2)) +@test isequal(acosh(MPCComplex(5.0,Inf)),MPCComplex(Inf,pi/2)) +@test isequal(acosh(MPCComplex(5.0,-Inf)),MPCComplex(Inf,-pi/2)) + +@test isequal(acosh(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) + +@test isequal(acosh(MPCComplex(-Inf,0.0)),MPCComplex(Inf,pi)) +@test isequal(acosh(MPCComplex(-Inf,-0.0)),MPCComplex(Inf,-pi)) +@test isequal(acosh(MPCComplex(-Inf,5.0)),MPCComplex(Inf,pi)) +@test isequal(acosh(MPCComplex(-Inf,-5.0)),MPCComplex(Inf,-pi)) + +@test isequal(acosh(MPCComplex(Inf,0.0)),MPCComplex(Inf,0.0)) +@test isequal(acosh(MPCComplex(Inf,-0.0)),MPCComplex(Inf,-0.0)) +@test isequal(acosh(MPCComplex(Inf,5.0)),MPCComplex(Inf,0.0)) +@test isequal(acosh(MPCComplex(Inf,-5.0)),MPCComplex(Inf,-0.0)) + +@test isequal(acosh(MPCComplex(-Inf,Inf)),MPCComplex(Inf,3*pi/4)) +@test isequal(acosh(MPCComplex(-Inf,-Inf)),MPCComplex(Inf,-3*pi/4)) + +@test isequal(acosh(MPCComplex(Inf,Inf)),MPCComplex(Inf,pi/4)) +@test isequal(acosh(MPCComplex(Inf,-Inf)),MPCComplex(Inf,-pi/4)) + +@test isequal(acosh(MPCComplex(Inf,NaN)),MPCComplex(Inf,NaN)) +@test isequal(acosh(MPCComplex(-Inf,NaN)),MPCComplex(Inf,NaN)) + +@test isequal(acosh(MPCComplex(NaN,Inf)),MPCComplex(Inf,NaN)) +@test isequal(acosh(MPCComplex(NaN,-Inf)),MPCComplex(Inf,NaN)) + +@test isequal(acosh(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) + + +# acos +# acos(conj(z)) = conj(acos(z)) +@test isequal(acos(MPCComplex(0.0,0.0)),MPCComplex(pi/2,-0.0)) +@test isequal(acos(MPCComplex(0.0,-0.0)),MPCComplex(pi/2,0.0)) +@test isequal(acos(MPCComplex(-0.0,0.0)),MPCComplex(pi/2,-0.0)) +@test isequal(acos(MPCComplex(-0.0,-0.0)),MPCComplex(pi/2,0.0)) + +@test isequal(acos(MPCComplex(0.0,NaN)),MPCComplex(pi/2,NaN)) +@test isequal(acos(MPCComplex(-0.0,NaN)),MPCComplex(pi/2,NaN)) + +@test isequal(acos(MPCComplex(0.0,Inf)),MPCComplex(pi/2,-Inf)) +@test isequal(acos(MPCComplex(0.0,-Inf)),MPCComplex(pi/2,Inf)) +@test isequal(acos(MPCComplex(5.0,Inf)),MPCComplex(pi/2,-Inf)) +@test isequal(acos(MPCComplex(5.0,-Inf)),MPCComplex(pi/2,Inf)) + +@test isequal(acos(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) + +@test isequal(acos(MPCComplex(-Inf,0.0)),MPCComplex(pi,-Inf)) +@test isequal(acos(MPCComplex(-Inf,-0.0)),MPCComplex(pi,Inf)) +@test isequal(acos(MPCComplex(-Inf,5.0)),MPCComplex(pi,-Inf)) +@test isequal(acos(MPCComplex(-Inf,-5.0)),MPCComplex(pi,Inf)) + +@test isequal(acos(MPCComplex(Inf,0.0)),MPCComplex(0.0,-Inf)) +@test isequal(acos(MPCComplex(Inf,-0.0)),MPCComplex(0.0,Inf)) +@test isequal(acos(MPCComplex(Inf,5.0)),MPCComplex(0.0,-Inf)) +@test isequal(acos(MPCComplex(Inf,-5.0)),MPCComplex(0.0,Inf)) + +@test isequal(acos(MPCComplex(-Inf,Inf)),MPCComplex(3*pi/4,-Inf)) +@test isequal(acos(MPCComplex(-Inf,-Inf)),MPCComplex(3*pi/4,Inf)) + +@test isequal(acos(MPCComplex(Inf,Inf)),MPCComplex(pi/4,-Inf)) +@test isequal(acos(MPCComplex(Inf,-Inf)),MPCComplex(pi/4,Inf)) + +# TODO: The left side evaluates to MPCComplex(NaN, -Inf) +#@test isequal(acos(MPCComplex(Inf,NaN)),MPCComplex(NaN,Inf)) +#@test isequal(acos(MPCComplex(-Inf,NaN)),MPCComplex(NaN,Inf)) + +@test isequal(acos(MPCComplex(NaN,0.0)),MPCComplex(NaN,NaN)) +@test isequal(acos(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) + +@test isequal(acos(MPCComplex(NaN,Inf)),MPCComplex(NaN,-Inf)) +@test isequal(acos(MPCComplex(NaN,-Inf)),MPCComplex(NaN,Inf)) + +@test isequal(acos(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) + + + +# asinh +# asinh(conj(z)) = conj(asinh(z)) +# asinh(-z) = -asinh(z) +@test isequal(asinh(MPCComplex(0.0,0.0)),MPCComplex(0.0,0.0)) +@test isequal(asinh(MPCComplex(0.0,-0.0)),MPCComplex(0.0,-0.0)) +@test isequal(asinh(MPCComplex(-0.0,0.0)),MPCComplex(-0.0,0.0)) +@test isequal(asinh(MPCComplex(-0.0,-0.0)),MPCComplex(-0.0,-0.0)) + +@test isequal(asinh(MPCComplex(0.0,Inf)),MPCComplex(Inf,pi/2)) +@test isequal(asinh(MPCComplex(0.0,-Inf)),MPCComplex(Inf,-pi/2)) +@test isequal(asinh(MPCComplex(-0.0,Inf)),MPCComplex(-Inf,pi/2)) +@test isequal(asinh(MPCComplex(-0.0,-Inf)),MPCComplex(-Inf,-pi/2)) + +@test isequal(asinh(MPCComplex(5.0,Inf)),MPCComplex(Inf,pi/2)) +@test isequal(asinh(MPCComplex(5.0,-Inf)),MPCComplex(Inf,-pi/2)) +@test isequal(asinh(MPCComplex(-5.0,Inf)),MPCComplex(-Inf,pi/2)) +@test isequal(asinh(MPCComplex(-5.0,-Inf)),MPCComplex(-Inf,-pi/2)) + +@test isequal(asinh(MPCComplex(0.0,NaN)),MPCComplex(NaN,NaN)) +@test isequal(asinh(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) + +@test isequal(asinh(MPCComplex(Inf,Inf)),MPCComplex(Inf,pi/4)) +@test isequal(asinh(MPCComplex(Inf,-Inf)),MPCComplex(Inf,-pi/4)) +@test isequal(asinh(MPCComplex(-Inf,Inf)),MPCComplex(-Inf,pi/4)) +@test isequal(asinh(MPCComplex(-Inf,-Inf)),MPCComplex(-Inf,-pi/4)) + +@test isequal(asinh(MPCComplex(Inf,NaN)),MPCComplex(Inf,NaN)) +@test isequal(asinh(MPCComplex(-Inf,NaN)),MPCComplex(-Inf,NaN)) + +@test isequal(asinh(MPCComplex(NaN,0.0)),MPCComplex(NaN,0.0)) +@test isequal(asinh(MPCComplex(NaN,-0.0)),MPCComplex(NaN,-0.0)) + +@test isequal(asinh(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) + +@test isequal(asinh(MPCComplex(NaN,Inf)),MPCComplex(Inf,NaN)) +@test isequal(asinh(MPCComplex(NaN,-Inf)),MPCComplex(Inf,NaN)) + +@test isequal(asinh(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) + + +# asin +# asin(z) = -i*asinh(iz) +@test isequal(asin(MPCComplex(0.0,0.0)),MPCComplex(0.0,0.0)) +@test isequal(asin(MPCComplex(0.0,-0.0)),MPCComplex(0.0,-0.0)) +@test isequal(asin(MPCComplex(-0.0,0.0)),MPCComplex(-0.0,0.0)) +@test isequal(asin(MPCComplex(-0.0,-0.0)),MPCComplex(-0.0,-0.0)) + +@test isequal(asin(MPCComplex(Inf,0.0)),MPCComplex(pi/2,Inf)) +@test isequal(asin(MPCComplex(-Inf,0.0)),MPCComplex(-pi/2,Inf)) +@test isequal(asin(MPCComplex(Inf,-0.0)),MPCComplex(pi/2,-Inf)) +@test isequal(asin(MPCComplex(-Inf,-0.0)),MPCComplex(-pi/2,-Inf)) + +@test isequal(asin(MPCComplex(Inf,5.0)),MPCComplex(pi/2,Inf)) +@test isequal(asin(MPCComplex(-Inf,5.0)),MPCComplex(-pi/2,Inf)) +@test isequal(asin(MPCComplex(Inf,-5.0)),MPCComplex(pi/2,-Inf)) +@test isequal(asin(MPCComplex(-Inf,-5.0)),MPCComplex(-pi/2,-Inf)) + +@test isequal(asin(MPCComplex(NaN,0.0)),MPCComplex(NaN,NaN)) +@test isequal(asin(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) + +@test isequal(asin(MPCComplex(Inf,Inf)),MPCComplex(pi/4,Inf)) +@test isequal(asin(MPCComplex(Inf,-Inf)),MPCComplex(pi/4,-Inf)) +@test isequal(asin(MPCComplex(-Inf,Inf)),MPCComplex(-pi/4,Inf)) +@test isequal(asin(MPCComplex(-Inf,-Inf)),MPCComplex(-pi/4,-Inf)) + +@test isequal(asin(MPCComplex(NaN,Inf)),MPCComplex(NaN,Inf)) +@test isequal(asin(MPCComplex(NaN,-Inf)),MPCComplex(NaN,-Inf)) + +@test isequal(asin(MPCComplex(0.0,NaN)),MPCComplex(0.0,NaN)) +@test isequal(asin(MPCComplex(-0.0,NaN)),MPCComplex(-0.0,NaN)) + +@test isequal(asin(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) + +@test isequal(asin(MPCComplex(Inf,NaN)),MPCComplex(NaN,Inf)) +@test isequal(asin(MPCComplex(-Inf,NaN)),MPCComplex(NaN,Inf)) + +@test isequal(asin(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) + + + +# atanh +# atanh(conj(z)) = conj(atanh(z)) +# atang(-z) = -atanh(z) + +@test isequal(atanh(MPCComplex(0.0,0.0)),MPCComplex(0.0,0.0)) +@test isequal(atanh(MPCComplex(0.0,-0.0)),MPCComplex(0.0,-0.0)) +@test isequal(atanh(MPCComplex(-0.0,0.0)),MPCComplex(-0.0,0.0)) +@test isequal(atanh(MPCComplex(-0.0,-0.0)),MPCComplex(-0.0,-0.0)) + +@test isequal(atanh(MPCComplex(0.0,NaN)),MPCComplex(0.0,NaN)) +@test isequal(atanh(MPCComplex(-0.0,NaN)),MPCComplex(-0.0,NaN)) + +# raise divide-by-zero flag +@test isequal(atanh(MPCComplex(1.0,0.0)),MPCComplex(Inf,0.0)) + +@test isequal(atanh(MPCComplex(0.0,Inf)),MPCComplex(0.0,pi/2)) +@test isequal(atanh(MPCComplex(0.0,-Inf)),MPCComplex(0.0,-pi/2)) +@test isequal(atanh(MPCComplex(-0.0,Inf)),MPCComplex(-0.0,pi/2)) +@test isequal(atanh(MPCComplex(-0.0,-Inf)),MPCComplex(-0.0,-pi/2)) + +@test isequal(atanh(MPCComplex(5.0,Inf)),MPCComplex(0.0,pi/2)) +@test isequal(atanh(MPCComplex(5.0,-Inf)),MPCComplex(0.0,-pi/2)) +@test isequal(atanh(MPCComplex(-5.0,Inf)),MPCComplex(-0.0,pi/2)) +@test isequal(atanh(MPCComplex(-5.0,-Inf)),MPCComplex(-0.0,-pi/2)) + +@test isequal(atanh(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) +@test isequal(atanh(MPCComplex(-5.0,NaN)),MPCComplex(NaN,NaN)) + +@test isequal(atanh(MPCComplex(Inf,0.0)),MPCComplex(0.0,pi/2)) +@test isequal(atanh(MPCComplex(Inf,-0.0)),MPCComplex(0.0,-pi/2)) +@test isequal(atanh(MPCComplex(-Inf,0.0)),MPCComplex(-0.0,pi/2)) +@test isequal(atanh(MPCComplex(-Inf,-0.0)),MPCComplex(-0.0,-pi/2)) + +@test isequal(atanh(MPCComplex(Inf,5.0)),MPCComplex(0.0,pi/2)) +@test isequal(atanh(MPCComplex(Inf,-5.0)),MPCComplex(0.0,-pi/2)) +@test isequal(atanh(MPCComplex(-Inf,5.0)),MPCComplex(-0.0,pi/2)) +@test isequal(atanh(MPCComplex(-Inf,-5.0)),MPCComplex(-0.0,-pi/2)) + +@test isequal(atanh(MPCComplex(Inf,Inf)),MPCComplex(0.0,pi/2)) +@test isequal(atanh(MPCComplex(Inf,-Inf)),MPCComplex(0.0,-pi/2)) +@test isequal(atanh(MPCComplex(-Inf,Inf)),MPCComplex(-0.0,pi/2)) +@test isequal(atanh(MPCComplex(-Inf,-Inf)),MPCComplex(-0.0,-pi/2)) + +@test isequal(atanh(MPCComplex(Inf,NaN)),MPCComplex(0.0,NaN)) +@test isequal(atanh(MPCComplex(-Inf,NaN)),MPCComplex(-0.0,NaN)) + +@test isequal(atanh(MPCComplex(NaN,0.0)),MPCComplex(NaN,NaN)) +@test isequal(atanh(MPCComplex(NaN,-0.0)),MPCComplex(NaN,NaN)) +@test isequal(atanh(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) +@test isequal(atanh(MPCComplex(NaN,-5.0)),MPCComplex(NaN,NaN)) + +@test isequal(atanh(MPCComplex(NaN,Inf)),MPCComplex(0.0,pi/2)) +@test isequal(atanh(MPCComplex(NaN,-Inf)),MPCComplex(0.0,-pi/2)) + +@test isequal(atanh(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) + + +# atan +# atan(z) = -i*tanh(iz) + +@test isequal(atan(MPCComplex(0.0,0.0)),MPCComplex(0.0,0.0)) +@test isequal(atan(MPCComplex(0.0,-0.0)),MPCComplex(0.0,-0.0)) +@test isequal(atan(MPCComplex(-0.0,0.0)),MPCComplex(-0.0,0.0)) +@test isequal(atan(MPCComplex(-0.0,-0.0)),MPCComplex(-0.0,-0.0)) + +@test isequal(atan(MPCComplex(NaN,0.0)),MPCComplex(NaN,0.0)) +@test isequal(atan(MPCComplex(NaN,-0.0)),MPCComplex(NaN,-0.0)) + +# raise divide-by-zero flag +@test isequal(atan(MPCComplex(0.0,1.0)),MPCComplex(0.0,Inf)) + +@test isequal(atan(MPCComplex(Inf,0.0)),MPCComplex(pi/2,0.0)) +@test isequal(atan(MPCComplex(-Inf,0.0)),MPCComplex(-pi/2,0.0)) +@test isequal(atan(MPCComplex(Inf,-0.0)),MPCComplex(pi/2,-0.0)) +@test isequal(atan(MPCComplex(-Inf,-0.0)),MPCComplex(-pi/2,-0.0)) + +@test isequal(atan(MPCComplex(Inf,5.0)),MPCComplex(pi/2,0.0)) +@test isequal(atan(MPCComplex(-Inf,5.0)),MPCComplex(-pi/2,0.0)) +@test isequal(atan(MPCComplex(Inf,-5.0)),MPCComplex(pi/2,-0.0)) +@test isequal(atan(MPCComplex(-Inf,-5.0)),MPCComplex(-pi/2,-0.0)) + +@test isequal(atan(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) +@test isequal(atan(MPCComplex(NaN,-5.0)),MPCComplex(NaN,NaN)) + +@test isequal(atan(MPCComplex(0.0,Inf)),MPCComplex(pi/2,0.0)) +@test isequal(atan(MPCComplex(-0.0,Inf)),MPCComplex(-pi/2,0.0)) +@test isequal(atan(MPCComplex(0.0,-Inf)),MPCComplex(pi/2,-0.0)) +@test isequal(atan(MPCComplex(-0.0,-Inf)),MPCComplex(-pi/2,-0.0)) + +@test isequal(atan(MPCComplex(5.0,Inf)),MPCComplex(pi/2,0.0)) +@test isequal(atan(MPCComplex(-5.0,Inf)),MPCComplex(-pi/2,0.0)) +@test isequal(atan(MPCComplex(5.0,-Inf)),MPCComplex(pi/2,-0.0)) +@test isequal(atan(MPCComplex(-5.0,-Inf)),MPCComplex(-pi/2,-0.0)) + +@test isequal(atan(MPCComplex(Inf,Inf)),MPCComplex(pi/2,0.0)) +@test isequal(atan(MPCComplex(Inf,-Inf)),MPCComplex(pi/2,-0.0)) +@test isequal(atan(MPCComplex(-Inf,Inf)),MPCComplex(-pi/2,0.0)) +@test isequal(atan(MPCComplex(-Inf,-Inf)),MPCComplex(-pi/2,-0.0)) + +@test isequal(atan(MPCComplex(NaN,Inf)),MPCComplex(NaN,0.0)) +@test isequal(atan(MPCComplex(NaN,-Inf)),MPCComplex(NaN,-0.0)) + +@test isequal(atan(MPCComplex(0.0,NaN)),MPCComplex(NaN,NaN)) +@test isequal(atan(MPCComplex(-0.0,NaN)),MPCComplex(NaN,NaN)) +@test isequal(atan(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) +@test isequal(atan(MPCComplex(-5.0,NaN)),MPCComplex(NaN,NaN)) + +@test isequal(atan(MPCComplex(Inf,NaN)),MPCComplex(pi/2,0.0)) +@test isequal(atan(MPCComplex(-Inf,NaN)),MPCComplex(-pi/2,0.0)) + +@test isequal(atan(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) + +end # end precision change From 1b9ba2738e0242531d48d8d0a86e5c08ae7f023c Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Fri, 26 Apr 2013 00:00:10 -0300 Subject: [PATCH 25/31] Add conjugate function to MPCComplex --- base/mpc.jl | 13 ++++++++++--- test/mpc.jl | 6 ++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/base/mpc.jl b/base/mpc.jl index 9d89c4a98084d..409b8885a565c 100644 --- a/base/mpc.jl +++ b/base/mpc.jl @@ -10,8 +10,9 @@ export import Base: (*), +, -, /, <, <<, >>, <=, ==, >, >=, ^, (~), (&), (|), ($), cmp, - complex, convert, div, exp, imag, integer_valued, isfinite, isinf, log, - promote_rule, real, show, showcompact, sqrt, string, get_precision, + complex, conj, convert, div, exp, imag, integer_valued, isfinite, + isinf, log, promote_rule, real, show, showcompact, sqrt, string, + get_precision, # trigonometric functions sin, cos, tan, acos, asin, atan, cosh, sinh, tanh, acosh, asinh, atanh @@ -293,6 +294,12 @@ function real(x::MPCComplex) return z end +function conj(x::MPCComplex) + z = MPCComplex() + ccall((:mpc_conj, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) + return z +end + string(x::MPCComplex) = "$(string(real(x))) + $(string(imag(x)))im" show(io::IO, b::MPCComplex) = print(io, string(b) * " with $(get_precision(b)) bits of precision") @@ -300,7 +307,7 @@ showcompact(io::IO, b::MPCComplex) = print(io, string(b)) function copy(x::MPCComplex) z = MPCComplex() - ccall((:mpc_set, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE) + ccall((:mpc_set, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) return z end diff --git a/test/mpc.jl b/test/mpc.jl index 35567afc3f9d7..9f14192c9b6f0 100644 --- a/test/mpc.jl +++ b/test/mpc.jl @@ -79,6 +79,12 @@ x = MPCComplex(12,42) @test !integer_valued(MPCComplex(2,3)) @test integer_valued(MPCComplex(2)) +# conj +@test isequal(conj(MPCComplex(2,1)), MPCComplex(2,-1)) +@test isequal(conj(MPCComplex(2.,NaN)), MPCComplex(2.,NaN)) +@test isequal(conj(MPCComplex(2.,Inf)), MPCComplex(2.,-Inf)) +@test isequal(conj(MPCComplex(2.,-Inf)), MPCComplex(2.,Inf)) + # Kahan tests from #2845 by @simonbyrne with_bigcomplex_precision(53,53) do # sqrt: From 4a01f1be46e694423317aace231050fef1555626 Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Fri, 26 Apr 2013 00:21:51 -0300 Subject: [PATCH 26/31] Add ldexp and atan2 functions to MPFRFloat As they are being used by @jiahao in the new Kahan complex functions, it is needed to have them in MPFRFloat. --- base/mpfr.jl | 23 +++++++++++++++++++++-- test/mpfr.jl | 15 +++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/base/mpfr.jl b/base/mpfr.jl index 2ea73d48290bf..94c071ea22e19 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -13,12 +13,12 @@ import Base: (*), +, -, /, <, <=, ==, >, >=, ^, besselj, besselj0, besselj1, bessely, bessely0, bessely1, ceil, cmp, convert, copysign, exp, exp2, exponent, factorial, floor, hypot, integer_valued, iround, isfinite, - isinf, isnan, log, log2, log10, max, min, mod, modf, nextfloat, + isinf, isnan, ldexp, log, log2, log10, max, min, mod, modf, nextfloat, prevfloat, promote_rule, rem, round, show, showcompact, sum, sqrt, string, trunc, get_precision, # import trigonometric functions sin, cos, tan, sec, csc, cot, acos, asin, atan, cosh, sinh, tanh, - sech, csch, coth, acosh, asinh, atanh + sech, csch, coth, acosh, asinh, atanh, atan2 const ROUNDING_MODE = [0] const DEFAULT_PRECISION = [256] @@ -376,6 +376,19 @@ function exp10(x::MPFRFloat) return z end +function ldexp(x::MPFRFloat, n::Clong) + z = MPFRFloat() + ccall((:mpfr_mul_2si, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Clong, Int32), &z, &x, n, ROUNDING_MODE[end]) + return z +end +function ldexp(x::MPFRFloat, n::Culong) + z = MPFRFloat() + ccall((:mpfr_mul_2ui, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Culong, Int32), &z, &x, n, ROUNDING_MODE[end]) + return z +end +ldexp(x::MPFRFloat, n::Signed) = ldexp(x, convert(Clong, n)) +ldexp(x::MPFRFloat, n::Unsigned) = ldexp(x, convert(Culong, n)) + function besselj0(x::MPFRFloat) z = MPFRFloat() ccall((:mpfr_j0, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) @@ -510,6 +523,12 @@ for f in (:sin,:cos,:tan,:sec,:csc,:cot,:acos,:asin,:atan, end end +function atan2(y::MPFRFloat, x::MPFRFloat) + z = MPFRFloat() + ccall((:mpfr_atan2, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &y, &x, ROUNDING_MODE[end]) + return z +end + # Utility functions ==(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_equal_p, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}), &x, &y) != 0 <=(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_lessequal_p, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}), &x, &y) != 0 diff --git a/test/mpfr.jl b/test/mpfr.jl index 0bd9cc6bab5b2..ac0d8aea2f249 100644 --- a/test/mpfr.jl +++ b/test/mpfr.jl @@ -328,6 +328,21 @@ end # hypot @test hypot(MPFRFloat(3), MPFRFloat(4)) == 5 +# atan2 +with_bigfloat_precision(53) do + @test isequal(atan2(12,2), atan2(MPFRFloat(12), MPFRFloat(2))) +end + +# ldexp +with_bigfloat_precision(53) do + @test ldexp(MPFRFloat(24.5), 72) == ldexp(24.5, 72) + @test ldexp(MPFRFloat(24.5), int16(72)) == ldexp(24.5, 72) + @test ldexp(MPFRFloat(24.5), -72) == ldexp(24.5, -72) + @test ldexp(MPFRFloat(24.5), int16(-72)) == ldexp(24.5, -72) + @test ldexp(MPFRFloat(24.5), uint(72)) == ldexp(24.5, 72) + @test ldexp(MPFRFloat(24.5), 0x48) == ldexp(24.5, 72) +end + # basic arithmetic # Signed addition a = MPFRFloat("123456789012345678901234567890") From 22e6f369b4d95377737e542d03935013e85edcc7 Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Fri, 3 May 2013 04:00:53 -0300 Subject: [PATCH 27/31] Fix Makefile after rebase --- Makefile | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 5acc8b1428340..738a27db34173 100644 --- a/Makefile +++ b/Makefile @@ -62,19 +62,11 @@ run-julia: JL_LIBS = julia-release julia-debug # private libraries, that are installed in $(PREFIX)/lib/julia -<<<<<<< HEAD JL_PRIVATE_LIBS = amd arpack camd ccolamd cholmod colamd \ fftw3 fftw3f fftw3_threads fftw3f_threads \ gmp grisu openlibm openlibm-extras pcre \ random Rmath spqr suitesparse_wrapper \ - umfpack z openblas mpfr -======= -JL_PRIVATE_LIBS = amd arpack cholmod colamd fftw3 fftw3f fftw3_threads \ - fftw3f_threads gmp grisu mpfr mpc \ - openlibm openlibm-extras pcre \ - random Rmath spqr suitesparse_wrapper \ - umfpack z openblas ->>>>>>> Add mpc to the build system and basic documentation + umfpack z openblas mpfr mpc PREFIX ?= julia-$(JULIA_COMMIT) install: From bec3c4f18a60fec916e0ab94f51bb66bbf9801f6 Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Fri, 3 May 2013 04:37:56 -0300 Subject: [PATCH 28/31] Basic rounding control available for MPFRFloat --- base/exports.jl | 3 +++ base/mpfr.jl | 30 ++++++++++++++++++++++++++++-- test/mpfr.jl | 16 ++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/base/exports.jl b/base/exports.jl index a03fac3290d78..5bdefeb644216 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -833,6 +833,9 @@ export set_bigcomplex_precision, with_bigfloat_precision, with_bigcomplex_precision, + get_bigfloat_rounding, + set_bigfloat_rounding, + with_bigfloat_rounding, # statistics cor, diff --git a/base/mpfr.jl b/base/mpfr.jl index 94c071ea22e19..43639026b04a9 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -7,8 +7,11 @@ export exp10, get_bigfloat_precision, set_bigfloat_precision, - with_bigfloat_precision - + with_bigfloat_precision, + set_bigfloat_rounding, + get_bigfloat_rounding, + with_bigfloat_rounding + import Base: (*), +, -, /, <, <=, ==, >, >=, ^, besselj, besselj0, besselj1, bessely, bessely0, bessely1, ceil, cmp, convert, copysign, exp, exp2, @@ -23,6 +26,13 @@ import const ROUNDING_MODE = [0] const DEFAULT_PRECISION = [256] +# Rounding modes +const RoundToNearest = 0 +const RoundToZero = 1 +const RoundUp = 2 +const RoundDown = 3 +const RoundAwayZero = 4 + # Basic type and initialization definitions type MPFRFloat <: FloatingPoint @@ -548,6 +558,14 @@ function set_bigfloat_precision(x::Int) DEFAULT_PRECISION[end] = x end +get_bigfloat_rounding() = ROUNDING_MODE[end] +function set_bigfloat_rounding(x::Int) + if x < 0 || x > 4 + throw(DomainError()) + end + ROUNDING_MODE[end] = x +end + function copysign(x::MPFRFloat, y::MPFRFloat) z = MPFRFloat() ccall((:mpfr_copysign, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) @@ -619,6 +637,14 @@ function with_bigfloat_precision(f::Function, precision::Integer) return ret end +function with_bigfloat_rounding(f::Function, rounding::Integer) + old_rounding = get_bigfloat_rounding() + set_bigfloat_rounding(rounding) + ret = f() + set_bigfloat_rounding(old_rounding) + return ret +end + function round(x::MPFRFloat, prec::Integer) if prec < 1 throw(DomainError()) diff --git a/test/mpfr.jl b/test/mpfr.jl index ac0d8aea2f249..cc367cf300c48 100644 --- a/test/mpfr.jl +++ b/test/mpfr.jl @@ -59,6 +59,22 @@ z = MPFRFloat(30) @test !(x >= z) @test !(y <= z) +# rounding modes +with_bigfloat_precision(4) do + # default mode is round to nearest + down, up = with_bigfloat_rounding(MPFR.RoundToNearest) do + MPFRFloat("0.0938"), MPFRFloat("0.102") + end + with_bigfloat_rounding(MPFR.RoundDown) do + @test MPFRFloat(0.1) == down + @test MPFRFloat(0.1) != up + end + with_bigfloat_rounding(MPFR.RoundUp) do + @test MPFRFloat(0.1) != down + @test MPFRFloat(0.1) == up + end +end + # ^ x = MPFRFloat(12) y = MPFRFloat(4) From 0eca14e1138c96e8c0e0d0fd1136337f313896bb Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Fri, 3 May 2013 04:59:44 -0300 Subject: [PATCH 29/31] Finally rename MPFRFloat to BigFloat and remove the old code --- base/bigfloat.jl | 133 ----------- base/exports.jl | 1 - base/gmp.jl | 3 +- base/mpc.jl | 38 ++-- base/mpfr.jl | 560 +++++++++++++++++++++++------------------------ base/sysimg.jl | 2 - test/bigfloat.jl | 80 ------- test/mpc.jl | 8 +- test/mpfr.jl | 335 +++++++++++++++++----------- test/runtests.jl | 2 +- 10 files changed, 500 insertions(+), 662 deletions(-) delete mode 100644 base/bigfloat.jl delete mode 100644 test/bigfloat.jl diff --git a/base/bigfloat.jl b/base/bigfloat.jl deleted file mode 100644 index e7701dab41965..0000000000000 --- a/base/bigfloat.jl +++ /dev/null @@ -1,133 +0,0 @@ -BigFloat_clear(mpf::Vector{Int32}) = ccall((:__gmpf_clear, :libgmp), Void, (Ptr{Void},), mpf) - -immutable BigFloat <: FloatingPoint - mpf::Vector{Int32} - function BigFloat() - z = Array(Int32, 6) - ccall((:__gmpf_init,:libgmp), Void, (Ptr{Void},), z) - b = new(z) - finalizer(b.mpf, BigFloat_clear) - return b - end -end - -function BigFloat(x::BigFloat) - z = BigFloat() - ccall((:__gmpf_set, :libgmp), Void, (Ptr{Void}, Ptr{Void}), z.mpf, x.mpf) - return z -end - -function BigFloat(x::String) - z = BigFloat() - err = ccall((:__gmpf_set_str, :libgmp), Int32, (Ptr{Void}, Ptr{Uint8}, Int32), z.mpf, bytestring(x), 0) - if err != 0; error("Invalid input"); end - return z -end - -function BigFloat(x::Float64) - z = BigFloat() - ccall((:__gmpf_set_d, :libgmp), Void, (Ptr{Void}, Float64), z.mpf, x) - return z -end - -function BigFloat(x::Uint) - z = BigFloat() - ccall((:__gmpf_set_ui, :libgmp), Void, (Ptr{Void}, Uint), z.mpf, x) - return z -end - -function BigFloat(x::Int) - z = BigFloat() - ccall((:__gmpf_set_si, :libgmp), Void, (Ptr{Void}, Int), z.mpf, x) - return z -end - -function BigFloat(x::BigInt) - z = BigFloat() - ccall((:__gmpf_set_z, :libgmp), Void, (Ptr{Void}, Ptr{BigInt}), z.mpf, &x) - return z -end - -BigFloat(x::Bool) = BigFloat(uint(x)) -BigFloat(x::Signed) = BigFloat(int(x)) -BigFloat(x::Unsigned) = BigFloat(uint(x)) -#BigFloat(x::Int128) = BigFloat(BigInt(x)) -#BigFloat(x::Uint128) = BigFloat(BigInt(x)) -if WORD_SIZE == 32 - BigFloat(x::Int64) = BigFloat(string(x)) - BigFloat(x::Uint64) = BigFloat(BigInt(x)) -end -BigFloat(x::Float32) = BigFloat(float64(x)) -BigFloat(x::Rational) = BigFloat(num(x)) / BigFloat(den(x)) - -convert(::Type{BigFloat}, x::Rational) = BigFloat(x) # to resolve ambiguity -convert(::Type{BigFloat}, x::Real) = BigFloat(x) - -convert(::Type{Float64}, x::BigFloat) = ccall((:__gmpf_get_d,:libgmp), Float64, (Ptr{Void},), x.mpf) -convert(::Type{FloatingPoint}, x::BigInt) = BigFloat(x) - -promote_rule{T<:Union(Integer,FloatingPoint)}(::Type{BigFloat}, ::Type{T}) = BigFloat -promote_rule{T<:FloatingPoint}(::Type{BigInt},::Type{T}) = BigFloat - - -# mpf doesn't have inf or nan -isnan(x::BigFloat) = false -isinf(x::BigFloat) = false - -# Binary ops -for (fJ, fC) in ((:+,:add), (:-,:sub), (:*,:mul), (:/,:div)) - @eval begin - function ($fJ)(x::BigFloat, y::BigFloat) - z = BigFloat() - ccall(($(string(:__gmpf_,fC)),:libgmp), Void, (Ptr{Void}, Ptr{Void}, Ptr{Void}), z.mpf, x.mpf, y.mpf) - return z - end - end -end - -function -(x::BigFloat) - z = BigFloat() - ccall((:__gmpf_neg, :libgmp), Void, (Ptr{Void}, Ptr{Void}), z.mpf, x.mpf) - return z -end - -function cmp(x::BigFloat, y::BigFloat) - ccall((:__gmpf_cmp, :libgmp), Int32, (Ptr{Void}, Ptr{Void}), x.mpf, y.mpf) -end - -for f in (:sqrt, :ceil, :floor, :trunc) - @eval begin - function ($f)(x::BigFloat) - z = BigFloat() - ccall(($(string(:__gmpf_,f)), :libgmp), Void, (Ptr{Void}, Ptr{Void}), z.mpf, x.mpf) - return z - end - end -end - -function ^(x::BigFloat, y::Uint) - z = BigFloat() - ccall((:__gmpf_pow_ui, :libgmp), Void, (Ptr{Void}, Ptr{Void}, Uint), z.mpf, x.mpf, y) - return z -end - -^(x::Float32, y::BigInt) = BigFloat(x)^y -^(x::Float64, y::BigInt) = BigFloat(x)^y - -==(x::BigFloat, y::BigFloat) = cmp(x,y) == 0 -<=(x::BigFloat, y::BigFloat) = cmp(x,y) <= 0 ->=(x::BigFloat, y::BigFloat) = cmp(x,y) >= 0 -<(x::BigFloat, y::BigFloat) = cmp(x,y) < 0 ->(x::BigFloat, y::BigFloat) = cmp(x,y) > 0 - -function string(x::BigFloat) - lng = 128 - for i = 1:2 - z = Array(Uint8, lng) - lng = ccall((:__gmp_snprintf,:libgmp), Int32, (Ptr{Uint8}, Uint, Ptr{Uint8}, Ptr{Void}...), z, lng, "%.Fe", x.mpf) - if lng < 128 || i == 2; return bytestring(convert(Ptr{Uint8}, z[1:lng])); end - end -end - -show(io::IO, b::BigFloat) = print(io, string(b)) -showcompact(io::IO, b::BigFloat) = print(io, string(b)) diff --git a/base/exports.jl b/base/exports.jl index 5bdefeb644216..b29ca955dd664 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -59,7 +59,6 @@ export LocalProcess, Matrix, MPCComplex, - MPFRFloat, ObjectIdDict, #Pipe, #PipeEnd, diff --git a/base/gmp.jl b/base/gmp.jl index 1321956e34bf8..be33590a5c93b 100644 --- a/base/gmp.jl +++ b/base/gmp.jl @@ -1,6 +1,6 @@ module GMP -export BigInt, BigFloat +export BigInt import Base.(*), @@ -50,6 +50,5 @@ type mpz_struct end include("bigint.jl") -include("bigfloat.jl") end # module diff --git a/base/mpc.jl b/base/mpc.jl index 409b8885a565c..544bcec508f72 100644 --- a/base/mpc.jl +++ b/base/mpc.jl @@ -7,11 +7,11 @@ export get_bigcomplex_precision, set_bigcomplex_precision, with_bigcomplex_precision - + import Base: (*), +, -, /, <, <<, >>, <=, ==, >, >=, ^, (~), (&), (|), ($), cmp, - complex, conj, convert, div, exp, imag, integer_valued, isfinite, - isinf, log, promote_rule, real, show, showcompact, sqrt, string, + complex, conj, convert, div, exp, imag, integer_valued, isfinite, + isinf, log, promote_rule, real, show, showcompact, sqrt, string, get_precision, # trigonometric functions @@ -66,13 +66,7 @@ end function MPCComplex(x::BigFloat) z = MPCComplex() - ccall((:mpc_set_f, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{Void}, Int32), &z, x.mpf, ROUNDING_MODE[end]) - return z -end - -function MPCComplex(x::MPFRFloat) - z = MPCComplex() - ccall((:mpc_set_fr, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) + ccall((:mpc_set_fr, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{BigFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end @@ -151,13 +145,7 @@ end function MPCComplex(x::BigFloat, y::BigFloat) z = MPCComplex() - ccall((:mpc_set_f_f, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{Void}, Ptr{Void}, Int32), &z, x.mpf, y.mpf, ROUNDING_MODE[end]) - return z -end - -function MPCComplex(x::MPFRFloat, y::MPFRFloat) - z = MPCComplex() - ccall((:mpc_set_fr_fr, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) + ccall((:mpc_set_fr_fr, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) return z end @@ -171,8 +159,8 @@ if WORD_SIZE == 32 MPCComplex(x::Uint64, y::Uint64) = MPCComplex(BigInt(x), BigInt(y)) end MPCComplex(x::Float32, y::Float32) = MPCComplex(float64(x), float64(y)) -MPCComplex(x::Rational, y::Rational) = MPCComplex(MPFRFloat(num(x))/MPFRFloat(den(x)), - MPFRFloat(num(y))/MPFRFloat(den(y))) +MPCComplex(x::Rational, y::Rational) = MPCComplex(BigFloat(num(x))/BigFloat(den(x)), + BigFloat(num(y))/BigFloat(den(y))) # Basic operations @@ -280,17 +268,17 @@ with_bigcomplex_precision(f::Function, prec::Integer) = with_bigcomplex_precisio function imag(x::MPCComplex) z = with_bigfloat_precision(get_bigcomplex_precision()[end]) do - MPFRFloat() + BigFloat() end - ccall((:mpc_imag, :libmpc), Int32, (Ptr{MPFRFloat}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) + ccall((:mpc_imag, :libmpc), Int32, (Ptr{BigFloat}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) return z end function real(x::MPCComplex) z = with_bigfloat_precision(get_bigcomplex_precision()[1]) do - MPFRFloat() + BigFloat() end - ccall((:mpc_real, :libmpc), Int32, (Ptr{MPFRFloat}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) + ccall((:mpc_real, :libmpc), Int32, (Ptr{BigFloat}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) return z end @@ -313,8 +301,8 @@ end # Internal functions # Unsafe for general use -realref(x::MPCComplex) = MPFRFloat(x.reprec, x.resign, x.reexp, x.red) -imagref(x::MPCComplex) = MPFRFloat(x.imprec, x.imsign, x.imexp, x.imd) +realref(x::MPCComplex) = BigFloat(x.reprec, x.resign, x.reexp, x.red) +imagref(x::MPCComplex) = BigFloat(x.imprec, x.imsign, x.imexp, x.imd) realint(x::MPCComplex) = ccall((:mpfr_integer_p, :libmpfr), Int32, (Ptr{Void},), &(realref(x))) != 0 imagint(x::MPCComplex) = ccall((:mpfr_integer_p, :libmpfr), Int32, (Ptr{Void},), &(imagref(x))) != 0 diff --git a/base/mpfr.jl b/base/mpfr.jl index 43639026b04a9..fdc4e8ecd1e69 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -2,7 +2,7 @@ module MPFR export # Types - MPFRFloat, + BigFloat, # Functions exp10, get_bigfloat_precision, @@ -35,305 +35,297 @@ const RoundAwayZero = 4 # Basic type and initialization definitions -type MPFRFloat <: FloatingPoint +type BigFloat <: FloatingPoint prec::Clong sign::Cint exp::Clong d::Ptr{Void} - function MPFRFloat() + function BigFloat() N = get_bigfloat_precision() z = new(zero(Clong), zero(Cint), zero(Clong), C_NULL) - ccall((:mpfr_init2,:libmpfr), Void, (Ptr{MPFRFloat}, Clong), &z, N) + ccall((:mpfr_init2,:libmpfr), Void, (Ptr{BigFloat}, Clong), &z, N) finalizer(z, MPFR_clear) return z end # Not recommended for general use - function MPFRFloat(prec::Clong, sign::Cint, exp::Clong, d::Ptr{Void}) + function BigFloat(prec::Clong, sign::Cint, exp::Clong, d::Ptr{Void}) new(prec, sign, exp, d) end end -MPFR_clear(mpfr::MPFRFloat) = ccall((:mpfr_clear, :libmpfr), Void, (Ptr{MPFRFloat},), &mpfr) +MPFR_clear(mpfr::BigFloat) = ccall((:mpfr_clear, :libmpfr), Void, (Ptr{BigFloat},), &mpfr) -MPFRFloat(x::MPFRFloat) = x +BigFloat(x::BigFloat) = x for (fJ, fC) in ((:si,:Int), (:ui,:Uint), (:d,:Float64)) @eval begin - function MPFRFloat(x::($fC)) - z = MPFRFloat() - ccall(($(string(:mpfr_set_,fJ)), :libmpfr), Int32, (Ptr{MPFRFloat}, ($fC), Int32), &z, x, ROUNDING_MODE[end]) + function BigFloat(x::($fC)) + z = BigFloat() + ccall(($(string(:mpfr_set_,fJ)), :libmpfr), Int32, (Ptr{BigFloat}, ($fC), Int32), &z, x, ROUNDING_MODE[end]) return z end end end -function MPFRFloat(x::BigInt) - z = MPFRFloat() - ccall((:mpfr_set_z, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{BigInt}, Int32), &z, &x, ROUNDING_MODE[end]) +function BigFloat(x::BigInt) + z = BigFloat() + ccall((:mpfr_set_z, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigInt}, Int32), &z, &x, ROUNDING_MODE[end]) return z end -function MPFRFloat(x::BigFloat) - z = MPFRFloat() - ccall((:mpfr_set_f, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{Void}, Int32), &z, x.mpf, ROUNDING_MODE[end]) - return z -end - -function MPFRFloat(x::String, base::Int) - z = MPFRFloat() - err = ccall((:mpfr_set_str, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{Uint8}, Int32, Int32), &z, x, base, ROUNDING_MODE[end]) +function BigFloat(x::String, base::Int) + z = BigFloat() + err = ccall((:mpfr_set_str, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{Uint8}, Int32, Int32), &z, x, base, ROUNDING_MODE[end]) if err != 0; error("Invalid input"); end return z end -MPFRFloat(x::String) = MPFRFloat(x, 10) +BigFloat(x::String) = BigFloat(x, 10) -MPFRFloat(x::Bool) = MPFRFloat(uint(x)) -MPFRFloat(x::Signed) = MPFRFloat(int(x)) -MPFRFloat(x::Unsigned) = MPFRFloat(uint(x)) +BigFloat(x::Bool) = BigFloat(uint(x)) +BigFloat(x::Signed) = BigFloat(int(x)) +BigFloat(x::Unsigned) = BigFloat(uint(x)) if WORD_SIZE == 32 - MPFRFloat(x::Int64) = MPFRFloat(string(x)) - MPFRFloat(x::Uint64) = MPFRFloat(BigInt(x)) + BigFloat(x::Int64) = BigFloat(string(x)) + BigFloat(x::Uint64) = BigFloat(BigInt(x)) end -MPFRFloat(x::Float32) = MPFRFloat(float64(x)) -MPFRFloat(x::Rational) = MPFRFloat(num(x)) / MPFRFloat(den(x)) +BigFloat(x::Float32) = BigFloat(float64(x)) +BigFloat(x::Rational) = BigFloat(num(x)) / BigFloat(den(x)) -convert(::Type{MPFRFloat}, x::Rational) = MPFRFloat(x) # to resolve ambiguity -convert(::Type{MPFRFloat}, x::Real) = MPFRFloat(x) +convert(::Type{BigFloat}, x::Rational) = BigFloat(x) # to resolve ambiguity +convert(::Type{BigFloat}, x::Real) = BigFloat(x) -convert(::Type{Int64}, x::MPFRFloat) = int64(convert(Clong, x)) -convert(::Type{Int32}, x::MPFRFloat) = int32(convert(Clong, x)) -convert(::Type{Clong}, x::MPFRFloat) = integer_valued(x) ? - ccall((:mpfr_get_si,:libmpfr), Clong, (Ptr{MPFRFloat}, Int32), &x, ROUNDING_MODE[end]) : +convert(::Type{Int64}, x::BigFloat) = int64(convert(Clong, x)) +convert(::Type{Int32}, x::BigFloat) = int32(convert(Clong, x)) +convert(::Type{Clong}, x::BigFloat) = integer_valued(x) ? + ccall((:mpfr_get_si,:libmpfr), Clong, (Ptr{BigFloat}, Int32), &x, ROUNDING_MODE[end]) : throw(InexactError()) -convert(::Type{Uint32}, x::MPFRFloat) = uint64(convert(Culong, x)) -convert(::Type{Uint32}, x::MPFRFloat) = uint32(convert(Culong, x)) -convert(::Type{Culong}, x::MPFRFloat) = integer_valued(x) ? - ccall((:mpfr_get_ui,:libmpfr), Culong, (Ptr{MPFRFloat}, Int32), &x, ROUNDING_MODE[end]) : +convert(::Type{Uint32}, x::BigFloat) = uint64(convert(Culong, x)) +convert(::Type{Uint32}, x::BigFloat) = uint32(convert(Culong, x)) +convert(::Type{Culong}, x::BigFloat) = integer_valued(x) ? + ccall((:mpfr_get_ui,:libmpfr), Culong, (Ptr{BigFloat}, Int32), &x, ROUNDING_MODE[end]) : throw(InexactError()) -function convert(::Type{BigInt}, x::MPFRFloat) +function convert(::Type{BigInt}, x::BigFloat) if integer_valued(x) z = BigInt() - ccall((:mpfr_get_z,:libmpfr), Int32, (Ptr{BigInt}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) + ccall((:mpfr_get_z,:libmpfr), Int32, (Ptr{BigInt}, Ptr{BigFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z else throw(InexactError()) end end -convert(::Type{Float64}, x::MPFRFloat) = ccall((:mpfr_get_d,:libmpfr), Float64, (Ptr{MPFRFloat},), &x) -convert(::Type{Float32}, x::MPFRFloat) = ccall((:mpfr_get_flt,:libmpfr), Float32, (Ptr{MPFRFloat},), &x) - -promote_rule{T<:Real}(::Type{MPFRFloat}, ::Type{T}) = MPFRFloat +convert(::Type{Float64}, x::BigFloat) = ccall((:mpfr_get_d,:libmpfr), Float64, (Ptr{BigFloat},), &x) +convert(::Type{Float32}, x::BigFloat) = ccall((:mpfr_get_flt,:libmpfr), Float32, (Ptr{BigFloat},), &x) +promote_rule{T<:Real}(::Type{BigFloat}, ::Type{T}) = BigFloat -# TODO: Decide if overwriting the default BigFloat rule is good -promote_rule{T<:FloatingPoint}(::Type{BigInt},::Type{T}) = MPFRFloat -promote_rule{T<:FloatingPoint}(::Type{BigFloat},::Type{T}) = MPFRFloat +promote_rule{T<:FloatingPoint}(::Type{BigInt},::Type{T}) = BigFloat +promote_rule{T<:FloatingPoint}(::Type{BigFloat},::Type{T}) = BigFloat # Basic arithmetic without promotion # Unsigned addition -function +(x::MPFRFloat, c::Culong) - z = MPFRFloat() - ccall((:mpfr_add_ui, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Culong, Int32), &z, &x, c, ROUNDING_MODE[end]) +function +(x::BigFloat, c::Culong) + z = BigFloat() + ccall((:mpfr_add_ui, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Culong, Int32), &z, &x, c, ROUNDING_MODE[end]) return z end -+(c::Culong, x::MPFRFloat) = x + c -+(c::Unsigned, x::MPFRFloat) = x + convert(Culong, c) -+(x::MPFRFloat, c::Unsigned) = x + convert(Culong, c) ++(c::Culong, x::BigFloat) = x + c ++(c::Unsigned, x::BigFloat) = x + convert(Culong, c) ++(x::BigFloat, c::Unsigned) = x + convert(Culong, c) # Signed addition -function +(x::MPFRFloat, c::Clong) - z = MPFRFloat() - ccall((:mpfr_add_si, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Clong, Int32), &z, &x, c, ROUNDING_MODE[end]) +function +(x::BigFloat, c::Clong) + z = BigFloat() + ccall((:mpfr_add_si, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Clong, Int32), &z, &x, c, ROUNDING_MODE[end]) return z end -+(c::Clong, x::MPFRFloat) = x + c -+(x::MPFRFloat, c::Signed) = x + convert(Clong, c) -+(c::Signed, x::MPFRFloat) = x + convert(Clong, c) ++(c::Clong, x::BigFloat) = x + c ++(x::BigFloat, c::Signed) = x + convert(Clong, c) ++(c::Signed, x::BigFloat) = x + convert(Clong, c) # Float64 addition -function +(x::MPFRFloat, c::Float64) - z = MPFRFloat() - ccall((:mpfr_add_d, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Float64, Int32), &z, &x, c, ROUNDING_MODE[end]) +function +(x::BigFloat, c::Float64) + z = BigFloat() + ccall((:mpfr_add_d, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Float64, Int32), &z, &x, c, ROUNDING_MODE[end]) return z end -+(c::Float64, x::MPFRFloat) = x + c -+(c::Float32, x::MPFRFloat) = x + convert(Float64, c) -+(x::MPFRFloat, c::Float32) = x + convert(Float64, c) ++(c::Float64, x::BigFloat) = x + c ++(c::Float32, x::BigFloat) = x + convert(Float64, c) ++(x::BigFloat, c::Float32) = x + convert(Float64, c) # BigInt addition -function +(x::MPFRFloat, c::BigInt) - z = MPFRFloat() - ccall((:mpfr_add_z, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{BigInt}, Int32), &z, &x, &c, ROUNDING_MODE[end]) +function +(x::BigFloat, c::BigInt) + z = BigFloat() + ccall((:mpfr_add_z, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Ptr{BigInt}, Int32), &z, &x, &c, ROUNDING_MODE[end]) return z end -+(c::BigInt, x::MPFRFloat) = x + c ++(c::BigInt, x::BigFloat) = x + c # Unsigned subtraction -function -(x::MPFRFloat, c::Culong) - z = MPFRFloat() - ccall((:mpfr_sub_ui, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Culong, Int32), &z, &x, c, ROUNDING_MODE[end]) +function -(x::BigFloat, c::Culong) + z = BigFloat() + ccall((:mpfr_sub_ui, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Culong, Int32), &z, &x, c, ROUNDING_MODE[end]) return z end -function -(c::Culong, x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_ui_sub, :libmpfr), Int32, (Ptr{MPFRFloat}, Culong, Ptr{MPFRFloat}, Int32), &z, c, &x, ROUNDING_MODE[end]) +function -(c::Culong, x::BigFloat) + z = BigFloat() + ccall((:mpfr_ui_sub, :libmpfr), Int32, (Ptr{BigFloat}, Culong, Ptr{BigFloat}, Int32), &z, c, &x, ROUNDING_MODE[end]) return z end --(x::MPFRFloat, c::Unsigned) = -(x, convert(Culong, c)) --(c::Unsigned, x::MPFRFloat) = -(convert(Culong, c), x) +-(x::BigFloat, c::Unsigned) = -(x, convert(Culong, c)) +-(c::Unsigned, x::BigFloat) = -(convert(Culong, c), x) # Signed subtraction -function -(x::MPFRFloat, c::Clong) - z = MPFRFloat() - ccall((:mpfr_sub_si, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Clong, Int32), &z, &x, c, ROUNDING_MODE[end]) +function -(x::BigFloat, c::Clong) + z = BigFloat() + ccall((:mpfr_sub_si, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Clong, Int32), &z, &x, c, ROUNDING_MODE[end]) return z end -function -(c::Clong, x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_si_sub, :libmpfr), Int32, (Ptr{MPFRFloat}, Clong, Ptr{MPFRFloat}, Int32), &z, c, &x, ROUNDING_MODE[end]) +function -(c::Clong, x::BigFloat) + z = BigFloat() + ccall((:mpfr_si_sub, :libmpfr), Int32, (Ptr{BigFloat}, Clong, Ptr{BigFloat}, Int32), &z, c, &x, ROUNDING_MODE[end]) return z end --(x::MPFRFloat, c::Signed) = -(x, convert(Clong, c)) --(c::Signed, x::MPFRFloat) = -(convert(Clong, c), x) +-(x::BigFloat, c::Signed) = -(x, convert(Clong, c)) +-(c::Signed, x::BigFloat) = -(convert(Clong, c), x) # Float64 subtraction -function -(x::MPFRFloat, c::Float64) - z = MPFRFloat() - ccall((:mpfr_sub_d, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Float64, Int32), &z, &x, c, ROUNDING_MODE[end]) +function -(x::BigFloat, c::Float64) + z = BigFloat() + ccall((:mpfr_sub_d, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Float64, Int32), &z, &x, c, ROUNDING_MODE[end]) return z end -function -(c::Float64, x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_d_sub, :libmpfr), Int32, (Ptr{MPFRFloat}, Float64, Ptr{MPFRFloat}, Int32), &z, c, &x, ROUNDING_MODE[end]) +function -(c::Float64, x::BigFloat) + z = BigFloat() + ccall((:mpfr_d_sub, :libmpfr), Int32, (Ptr{BigFloat}, Float64, Ptr{BigFloat}, Int32), &z, c, &x, ROUNDING_MODE[end]) return z end --(x::MPFRFloat, c::Float32) = -(x, convert(Float64, c)) --(c::Float32, x::MPFRFloat) = -(convert(Float64, c), x) +-(x::BigFloat, c::Float32) = -(x, convert(Float64, c)) +-(c::Float32, x::BigFloat) = -(convert(Float64, c), x) # BigInt subtraction -function -(x::MPFRFloat, c::BigInt) - z = MPFRFloat() - ccall((:mpfr_sub_z, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{BigInt}, Int32), &z, &x, &c, ROUNDING_MODE[end]) +function -(x::BigFloat, c::BigInt) + z = BigFloat() + ccall((:mpfr_sub_z, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Ptr{BigInt}, Int32), &z, &x, &c, ROUNDING_MODE[end]) return z end -function -(c::BigInt, x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_z_sub, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{BigInt}, Ptr{MPFRFloat}, Int32), &z, &c, &x, ROUNDING_MODE[end]) +function -(c::BigInt, x::BigFloat) + z = BigFloat() + ccall((:mpfr_z_sub, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigInt}, Ptr{BigFloat}, Int32), &z, &c, &x, ROUNDING_MODE[end]) return z end # Unsigned multiplication -function *(x::MPFRFloat, c::Culong) - z = MPFRFloat() - ccall((:mpfr_mul_ui, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Culong, Int32), &z, &x, c, ROUNDING_MODE[end]) +function *(x::BigFloat, c::Culong) + z = BigFloat() + ccall((:mpfr_mul_ui, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Culong, Int32), &z, &x, c, ROUNDING_MODE[end]) return z end -*(c::Culong, x::MPFRFloat) = x * c -*(c::Unsigned, x::MPFRFloat) = x * convert(Culong, c) -*(x::MPFRFloat, c::Unsigned) = x * convert(Culong, c) +*(c::Culong, x::BigFloat) = x * c +*(c::Unsigned, x::BigFloat) = x * convert(Culong, c) +*(x::BigFloat, c::Unsigned) = x * convert(Culong, c) # Signed multiplication -function *(x::MPFRFloat, c::Clong) - z = MPFRFloat() - ccall((:mpfr_mul_si, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Clong, Int32), &z, &x, c, ROUNDING_MODE[end]) +function *(x::BigFloat, c::Clong) + z = BigFloat() + ccall((:mpfr_mul_si, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Clong, Int32), &z, &x, c, ROUNDING_MODE[end]) return z end -*(c::Clong, x::MPFRFloat) = x * c -*(x::MPFRFloat, c::Signed) = x * convert(Clong, c) +*(c::Clong, x::BigFloat) = x * c +*(x::BigFloat, c::Signed) = x * convert(Clong, c) # Float64 multiplication -function *(x::MPFRFloat, c::Float64) - z = MPFRFloat() - ccall((:mpfr_mul_d, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Float64, Int32), &z, &x, c, ROUNDING_MODE[end]) +function *(x::BigFloat, c::Float64) + z = BigFloat() + ccall((:mpfr_mul_d, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Float64, Int32), &z, &x, c, ROUNDING_MODE[end]) return z end -*(c::Float64, x::MPFRFloat) = x * c -*(c::Float32, x::MPFRFloat) = x * convert(Float64, c) -*(x::MPFRFloat, c::Float32) = x * convert(Float64, c) +*(c::Float64, x::BigFloat) = x * c +*(c::Float32, x::BigFloat) = x * convert(Float64, c) +*(x::BigFloat, c::Float32) = x * convert(Float64, c) # BigInt multiplication -*(c::Signed, x::MPFRFloat) = x * convert(Clong, c) -function *(x::MPFRFloat, c::BigInt) - z = MPFRFloat() - ccall((:mpfr_mul_z, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{BigInt}, Int32), &z, &x, &c, ROUNDING_MODE[end]) +*(c::Signed, x::BigFloat) = x * convert(Clong, c) +function *(x::BigFloat, c::BigInt) + z = BigFloat() + ccall((:mpfr_mul_z, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Ptr{BigInt}, Int32), &z, &x, &c, ROUNDING_MODE[end]) return z end -*(c::BigInt, x::MPFRFloat) = x * c +*(c::BigInt, x::BigFloat) = x * c # Unsigned division -function /(x::MPFRFloat, c::Culong) - z = MPFRFloat() - ccall((:mpfr_div_ui, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Culong, Int32), &z, &x, c, ROUNDING_MODE[end]) +function /(x::BigFloat, c::Culong) + z = BigFloat() + ccall((:mpfr_div_ui, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Culong, Int32), &z, &x, c, ROUNDING_MODE[end]) return z end -function /(c::Culong, x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_ui_div, :libmpfr), Int32, (Ptr{MPFRFloat}, Culong, Ptr{MPFRFloat}, Int32), &z, c, &x, ROUNDING_MODE[end]) +function /(c::Culong, x::BigFloat) + z = BigFloat() + ccall((:mpfr_ui_div, :libmpfr), Int32, (Ptr{BigFloat}, Culong, Ptr{BigFloat}, Int32), &z, c, &x, ROUNDING_MODE[end]) return z end -/(x::MPFRFloat, c::Unsigned) = /(x, convert(Culong, c)) -/(c::Unsigned, x::MPFRFloat) = /(convert(Culong, c), x) +/(x::BigFloat, c::Unsigned) = /(x, convert(Culong, c)) +/(c::Unsigned, x::BigFloat) = /(convert(Culong, c), x) # Signed division -function /(x::MPFRFloat, c::Clong) - z = MPFRFloat() - ccall((:mpfr_div_si, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Clong, Int32), &z, &x, c, ROUNDING_MODE[end]) +function /(x::BigFloat, c::Clong) + z = BigFloat() + ccall((:mpfr_div_si, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Clong, Int32), &z, &x, c, ROUNDING_MODE[end]) return z end -function /(c::Clong, x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_si_div, :libmpfr), Int32, (Ptr{MPFRFloat}, Clong, Ptr{MPFRFloat}, Int32), &z, c, &x, ROUNDING_MODE[end]) +function /(c::Clong, x::BigFloat) + z = BigFloat() + ccall((:mpfr_si_div, :libmpfr), Int32, (Ptr{BigFloat}, Clong, Ptr{BigFloat}, Int32), &z, c, &x, ROUNDING_MODE[end]) return z end -/(x::MPFRFloat, c::Signed) = /(x, convert(Clong, c)) -/(c::Signed, x::MPFRFloat) = /(convert(Clong, c), x) +/(x::BigFloat, c::Signed) = /(x, convert(Clong, c)) +/(c::Signed, x::BigFloat) = /(convert(Clong, c), x) # Float64 division -function /(x::MPFRFloat, c::Float64) - z = MPFRFloat() - ccall((:mpfr_div_d, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Float64, Int32), &z, &x, c, ROUNDING_MODE[end]) +function /(x::BigFloat, c::Float64) + z = BigFloat() + ccall((:mpfr_div_d, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Float64, Int32), &z, &x, c, ROUNDING_MODE[end]) return z end -function /(c::Float64, x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_d_div, :libmpfr), Int32, (Ptr{MPFRFloat}, Float64, Ptr{MPFRFloat}, Int32), &z, c, &x, ROUNDING_MODE[end]) +function /(c::Float64, x::BigFloat) + z = BigFloat() + ccall((:mpfr_d_div, :libmpfr), Int32, (Ptr{BigFloat}, Float64, Ptr{BigFloat}, Int32), &z, c, &x, ROUNDING_MODE[end]) return z end -/(x::MPFRFloat, c::Float32) = /(x, convert(Float64, c)) -/(c::Float32, x::MPFRFloat) = /(convert(Float64, c), x) +/(x::BigFloat, c::Float32) = /(x, convert(Float64, c)) +/(c::Float32, x::BigFloat) = /(convert(Float64, c), x) # BigInt division -function /(x::MPFRFloat, c::BigInt) - z = MPFRFloat() - ccall((:mpfr_div_z, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{BigInt}, Int32), &z, &x, &c, ROUNDING_MODE[end]) +function /(x::BigFloat, c::BigInt) + z = BigFloat() + ccall((:mpfr_div_z, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Ptr{BigInt}, Int32), &z, &x, &c, ROUNDING_MODE[end]) return z end # Basic operations for (fJ, fC) in ((:+,:add), (:-,:sub), (:*,:mul), (:/,:div), (:^, :pow)) @eval begin - function ($fJ)(x::MPFRFloat, y::MPFRFloat) - z = MPFRFloat() - ccall(($(string(:mpfr_,fC)),:libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) + function ($fJ)(x::BigFloat, y::BigFloat) + z = BigFloat() + ccall(($(string(:mpfr_,fC)),:libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) return z end end end -function -(x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_neg, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) +function -(x::BigFloat) + z = BigFloat() + ccall((:mpfr_neg, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end -function cmp(x::MPFRFloat, y::MPFRFloat) - ccall((:mpfr_cmp, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}), &x, &y) +function cmp(x::BigFloat, y::BigFloat) + ccall((:mpfr_cmp, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}), &x, &y) end -function sqrt(x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_sqrt, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) +function sqrt(x::BigFloat) + z = BigFloat() + ccall((:mpfr_sqrt, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, ROUNDING_MODE[end]) if isnan(z) throw(DomainError()) end @@ -342,176 +334,176 @@ end for f in (:ceil, :floor, :trunc) @eval begin - function ($f)(x::MPFRFloat) - z = MPFRFloat() - ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}), &z, &x) + function ($f)(x::BigFloat) + z = BigFloat() + ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}), &z, &x) return z end end end -function ^(x::MPFRFloat, y::Unsigned) - z = MPFRFloat() - ccall((:mpfr_pow_ui, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Culong, Int32), &z, &x, y, ROUNDING_MODE[end]) +function ^(x::BigFloat, y::Unsigned) + z = BigFloat() + ccall((:mpfr_pow_ui, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Culong, Int32), &z, &x, y, ROUNDING_MODE[end]) return z end -function ^(x::MPFRFloat, y::Signed) - z = MPFRFloat() - ccall((:mpfr_pow_si, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Clong, Int32), &z, &x, y, ROUNDING_MODE[end]) +function ^(x::BigFloat, y::Signed) + z = BigFloat() + ccall((:mpfr_pow_si, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Clong, Int32), &z, &x, y, ROUNDING_MODE[end]) return z end -function ^(x::MPFRFloat, y::BigInt) - z = MPFRFloat() - ccall((:mpfr_pow_z, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{BigInt}, Int32), &z, &x, &y, ROUNDING_MODE[end]) +function ^(x::BigFloat, y::BigInt) + z = BigFloat() + ccall((:mpfr_pow_z, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Ptr{BigInt}, Int32), &z, &x, &y, ROUNDING_MODE[end]) return z end -function exp(x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_exp, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) +function exp(x::BigFloat) + z = BigFloat() + ccall((:mpfr_exp, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end -function exp2(x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_exp2, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) +function exp2(x::BigFloat) + z = BigFloat() + ccall((:mpfr_exp2, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end -function exp10(x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_exp10, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) +function exp10(x::BigFloat) + z = BigFloat() + ccall((:mpfr_exp10, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end -function ldexp(x::MPFRFloat, n::Clong) - z = MPFRFloat() - ccall((:mpfr_mul_2si, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Clong, Int32), &z, &x, n, ROUNDING_MODE[end]) +function ldexp(x::BigFloat, n::Clong) + z = BigFloat() + ccall((:mpfr_mul_2si, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Clong, Int32), &z, &x, n, ROUNDING_MODE[end]) return z end -function ldexp(x::MPFRFloat, n::Culong) - z = MPFRFloat() - ccall((:mpfr_mul_2ui, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Culong, Int32), &z, &x, n, ROUNDING_MODE[end]) +function ldexp(x::BigFloat, n::Culong) + z = BigFloat() + ccall((:mpfr_mul_2ui, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Culong, Int32), &z, &x, n, ROUNDING_MODE[end]) return z end -ldexp(x::MPFRFloat, n::Signed) = ldexp(x, convert(Clong, n)) -ldexp(x::MPFRFloat, n::Unsigned) = ldexp(x, convert(Culong, n)) +ldexp(x::BigFloat, n::Signed) = ldexp(x, convert(Clong, n)) +ldexp(x::BigFloat, n::Unsigned) = ldexp(x, convert(Culong, n)) -function besselj0(x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_j0, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) +function besselj0(x::BigFloat) + z = BigFloat() + ccall((:mpfr_j0, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end -function besselj1(x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_j1, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) +function besselj1(x::BigFloat) + z = BigFloat() + ccall((:mpfr_j1, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end -function besselj(n::Integer, x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_jn, :libmpfr), Int32, (Ptr{MPFRFloat}, Clong, Ptr{MPFRFloat}, Int32), &z, n, &x, ROUNDING_MODE[end]) +function besselj(n::Integer, x::BigFloat) + z = BigFloat() + ccall((:mpfr_jn, :libmpfr), Int32, (Ptr{BigFloat}, Clong, Ptr{BigFloat}, Int32), &z, n, &x, ROUNDING_MODE[end]) return z end -function bessely0(x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_y0, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) +function bessely0(x::BigFloat) + z = BigFloat() + ccall((:mpfr_y0, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end -function bessely1(x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_y1, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) +function bessely1(x::BigFloat) + z = BigFloat() + ccall((:mpfr_y1, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end -function bessely(n::Integer, x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_yn, :libmpfr), Int32, (Ptr{MPFRFloat}, Clong, Ptr{MPFRFloat}, Int32), &z, n, &x, ROUNDING_MODE[end]) +function bessely(n::Integer, x::BigFloat) + z = BigFloat() + ccall((:mpfr_yn, :libmpfr), Int32, (Ptr{BigFloat}, Clong, Ptr{BigFloat}, Int32), &z, n, &x, ROUNDING_MODE[end]) return z end -function factorial(x::MPFRFloat) +function factorial(x::BigFloat) if x < 0 || !integer_valued(x) throw(DomainError()) end ui = convert(Culong, x) - z = MPFRFloat() - ccall((:mpfr_fac_ui, :libmpfr), Int32, (Ptr{MPFRFloat}, Culong, Int32), &z, ui, ROUNDING_MODE[end]) + z = BigFloat() + ccall((:mpfr_fac_ui, :libmpfr), Int32, (Ptr{BigFloat}, Culong, Int32), &z, ui, ROUNDING_MODE[end]) return z end -function hypot(x::MPFRFloat, y::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_hypot, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) +function hypot(x::BigFloat, y::BigFloat) + z = BigFloat() + ccall((:mpfr_hypot, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) return z end -function log(x::MPFRFloat) +function log(x::BigFloat) if x < 0 throw(DomainError()) end - z = MPFRFloat() - ccall((:mpfr_log, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) + z = BigFloat() + ccall((:mpfr_log, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end -function log2(x::MPFRFloat) +function log2(x::BigFloat) if x < 0 throw(DomainError()) end - z = MPFRFloat() - ccall((:mpfr_log2, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) + z = BigFloat() + ccall((:mpfr_log2, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end -function log10(x::MPFRFloat) +function log10(x::BigFloat) if x < 0 throw(DomainError()) end - z = MPFRFloat() - ccall((:mpfr_log10, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) + z = BigFloat() + ccall((:mpfr_log10, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end -function max(x::MPFRFloat, y::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_max, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) +function max(x::BigFloat, y::BigFloat) + z = BigFloat() + ccall((:mpfr_max, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) return z end -function min(x::MPFRFloat, y::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_min, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) +function min(x::BigFloat, y::BigFloat) + z = BigFloat() + ccall((:mpfr_min, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) return z end -function modf(x::MPFRFloat) +function modf(x::BigFloat) if isinf(x) - return (MPFRFloat(NaN), x) + return (BigFloat(NaN), x) end - zint = MPFRFloat() - zfloat = MPFRFloat() - ccall((:mpfr_modf, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &zint, &zfloat, &x, ROUNDING_MODE[end]) + zint = BigFloat() + zfloat = BigFloat() + ccall((:mpfr_modf, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Ptr{BigFloat}, Int32), &zint, &zfloat, &x, ROUNDING_MODE[end]) return (zfloat, zint) end -function rem(x::MPFRFloat, y::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_remainder, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) +function rem(x::BigFloat, y::BigFloat) + z = BigFloat() + ccall((:mpfr_remainder, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) return z end -# function sum{T<:MPFRFloat}(arr::AbstractArray{T}) -# z = MPFRFloat() +# function sum{T<:BigFloat}(arr::AbstractArray{T}) +# z = BigFloat() # n = length(arr) # ptrarr = [pointer(&x) for x in arr] # ccall((:mpfr_sum, :libmpfr), Int32, -# (Ptr{MPFRFloat}, Ptr{Void}, Culong, Int32), +# (Ptr{BigFloat}, Ptr{Void}, Culong, Int32), # &z, ptrarr, n, ROUNDING_MODE[1]) # return z # end @@ -522,9 +514,9 @@ end for f in (:sin,:cos,:tan,:sec,:csc,:cot,:acos,:asin,:atan, :cosh,:sinh,:tanh,:sech,:csch,:coth,:acosh,:asinh,:atanh) @eval begin - function ($f)(x::MPFRFloat) - z = MPFRFloat() - ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) + function ($f)(x::BigFloat) + z = BigFloat() + ccall(($(string(:mpfr_,f)), :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, ROUNDING_MODE[end]) if isnan(z) throw(DomainError()) end @@ -533,21 +525,21 @@ for f in (:sin,:cos,:tan,:sec,:csc,:cot,:acos,:asin,:atan, end end -function atan2(y::MPFRFloat, x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_atan2, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &y, &x, ROUNDING_MODE[end]) +function atan2(y::BigFloat, x::BigFloat) + z = BigFloat() + ccall((:mpfr_atan2, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &y, &x, ROUNDING_MODE[end]) return z end # Utility functions -==(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_equal_p, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}), &x, &y) != 0 -<=(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_lessequal_p, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}), &x, &y) != 0 ->=(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_greaterequal_p, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}), &x, &y) != 0 -<(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_less_p, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}), &x, &y) != 0 ->(x::MPFRFloat, y::MPFRFloat) = ccall((:mpfr_greater_p, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}), &x, &y) != 0 +==(x::BigFloat, y::BigFloat) = ccall((:mpfr_equal_p, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}), &x, &y) != 0 +<=(x::BigFloat, y::BigFloat) = ccall((:mpfr_lessequal_p, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}), &x, &y) != 0 +>=(x::BigFloat, y::BigFloat) = ccall((:mpfr_greaterequal_p, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}), &x, &y) != 0 +<(x::BigFloat, y::BigFloat) = ccall((:mpfr_less_p, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}), &x, &y) != 0 +>(x::BigFloat, y::BigFloat) = ccall((:mpfr_greater_p, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}), &x, &y) != 0 -function get_precision(x::MPFRFloat) - return ccall((:mpfr_get_prec, :libmpfr), Clong, (Ptr{MPFRFloat},), &x) +function get_precision(x::BigFloat) + return ccall((:mpfr_get_prec, :libmpfr), Clong, (Ptr{BigFloat},), &x) end get_bigfloat_precision() = DEFAULT_PRECISION[end] @@ -566,31 +558,31 @@ function set_bigfloat_rounding(x::Int) ROUNDING_MODE[end] = x end -function copysign(x::MPFRFloat, y::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_copysign, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) +function copysign(x::BigFloat, y::BigFloat) + z = BigFloat() + ccall((:mpfr_copysign, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) return z end -function exponent(x::MPFRFloat) +function exponent(x::BigFloat) if x == 0 || !isfinite(x) throw(DomainError()) end # The '- 1' is to make it work as Base.exponent - return ccall((:mpfr_get_exp, :libmpfr), Clong, (Ptr{MPFRFloat},), &x) - 1 + return ccall((:mpfr_get_exp, :libmpfr), Clong, (Ptr{BigFloat},), &x) - 1 end -function integer_valued(x::MPFRFloat) - return ccall((:mpfr_integer_p, :libmpfr), Int32, (Ptr{MPFRFloat},), &x) != 0 +function integer_valued(x::BigFloat) + return ccall((:mpfr_integer_p, :libmpfr), Int32, (Ptr{BigFloat},), &x) != 0 end -function iround(x::MPFRFloat) - fits = ccall((:mpfr_fits_slong_p, :libmpfr), Int32, (Ptr{MPFRFloat}, Int32), &x, ROUNDING_MODE[end]) +function iround(x::BigFloat) + fits = ccall((:mpfr_fits_slong_p, :libmpfr), Int32, (Ptr{BigFloat}, Int32), &x, ROUNDING_MODE[end]) if fits != 0 - return ccall((:mpfr_get_si, :libmpfr), Clong, (Ptr{MPFRFloat}, Int32), &x, ROUNDING_MODE[end]) + return ccall((:mpfr_get_si, :libmpfr), Clong, (Ptr{BigFloat}, Int32), &x, ROUNDING_MODE[end]) end z = BigInt() - ccall((:mpfr_get_z, :libmpfr), Int32, (Ptr{BigInt}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) + ccall((:mpfr_get_z, :libmpfr), Int32, (Ptr{BigInt}, Ptr{BigFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end @@ -599,33 +591,33 @@ for (f,t) in ((:uint8,:Uint8), (:uint16,:Uint16), (:uint32,:Uint32), # requires int128/uint128(::Type{BigInt}) support # (:int128,:Int128), (:uint128,:Uint128), (:unsigned,:Uint), (:uint,:Uint)) - @eval iround(::Type{$t}, x::MPFRFloat) = ($f)(iround(x)) + @eval iround(::Type{$t}, x::BigFloat) = ($f)(iround(x)) end -isfinite(x::MPFRFloat) = !isinf(x) -function isinf(x::MPFRFloat) - return ccall((:mpfr_inf_p, :libmpfr), Int32, (Ptr{MPFRFloat},), &x) != 0 +isfinite(x::BigFloat) = !isinf(x) +function isinf(x::BigFloat) + return ccall((:mpfr_inf_p, :libmpfr), Int32, (Ptr{BigFloat},), &x) != 0 end -function isnan(x::MPFRFloat) - return ccall((:mpfr_nan_p, :libmpfr), Int32, (Ptr{MPFRFloat},), &x) != 0 +function isnan(x::BigFloat) + return ccall((:mpfr_nan_p, :libmpfr), Int32, (Ptr{BigFloat},), &x) != 0 end -function nextfloat(x::MPFRFloat) +function nextfloat(x::BigFloat) z = copy(x) - ccall((:mpfr_nextabove, :libmpfr), Int32, (Ptr{MPFRFloat},), &z) != 0 + ccall((:mpfr_nextabove, :libmpfr), Int32, (Ptr{BigFloat},), &z) != 0 return z end -function prevfloat(x::MPFRFloat) +function prevfloat(x::BigFloat) z = copy(x) - ccall((:mpfr_nextbelow, :libmpfr), Int32, (Ptr{MPFRFloat},), &z) != 0 + ccall((:mpfr_nextbelow, :libmpfr), Int32, (Ptr{BigFloat},), &z) != 0 return z end -function copy(x::MPFRFloat) - z = MPFRFloat() - ccall((:mpfr_set, :libmpfr), Int32, (Ptr{MPFRFloat}, Ptr{MPFRFloat}, Int32), &z, &x, ROUNDING_MODE[end]) +function copy(x::BigFloat) + z = BigFloat() + ccall((:mpfr_set, :libmpfr), Int32, (Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, ROUNDING_MODE[end]) return z end @@ -645,28 +637,28 @@ function with_bigfloat_rounding(f::Function, rounding::Integer) return ret end -function round(x::MPFRFloat, prec::Integer) +function round(x::BigFloat, prec::Integer) if prec < 1 throw(DomainError()) end prec = int(ceil(log2(10^prec))) - z = MPFRFloat(x) - ccall((:mpfr_prec_round, :libmpfr), Int32, (Ptr{MPFRFloat}, Clong, Int32), &z, prec, ROUNDING_MODE[end]) + z = BigFloat(x) + ccall((:mpfr_prec_round, :libmpfr), Int32, (Ptr{BigFloat}, Clong, Int32), &z, prec, ROUNDING_MODE[end]) return z end -function string(x::MPFRFloat) +function string(x::BigFloat) lng = 128 for i = 1:2 z = Array(Uint8, lng) - lng = ccall((:mpfr_snprintf,:libmpfr), Int32, (Ptr{Uint8}, Culong, Ptr{Uint8}, Ptr{MPFRFloat}...), z, lng, "%.Re", &x) + lng = ccall((:mpfr_snprintf,:libmpfr), Int32, (Ptr{Uint8}, Culong, Ptr{Uint8}, Ptr{BigFloat}...), z, lng, "%.Re", &x) if lng < 128 || i == 2 return bytestring(convert(Ptr{Uint8}, z[1:lng])) end end end -show(io::IO, b::MPFRFloat) = print(io, string(b) * " with $(get_precision(b)) bits of precision") -showcompact(io::IO, b::MPFRFloat) = print(io, string(b)) +show(io::IO, b::BigFloat) = print(io, string(b) * " with $(get_precision(b)) bits of precision") +showcompact(io::IO, b::BigFloat) = print(io, string(b)) end #module diff --git a/base/sysimg.jl b/base/sysimg.jl index 6cc7bdf404687..9ba66f78f0b3a 100644 --- a/base/sysimg.jl +++ b/base/sysimg.jl @@ -172,8 +172,6 @@ importall .DSP # BigInts and BigFloats include("gmp.jl") importall .GMP - -# MPFR and MPC include("mpfr.jl") importall .MPFR include("mpc.jl") diff --git a/test/bigfloat.jl b/test/bigfloat.jl deleted file mode 100644 index 988aa88e26c55..0000000000000 --- a/test/bigfloat.jl +++ /dev/null @@ -1,80 +0,0 @@ -tol = 1e-12 - -a = BigFloat("12.34567890121") -b = BigFloat("12.34567890122") - -@test_approx_eq_eps a+1e-11 b tol -@test !(b == a) -@test b > a -@test b >= a -@test !(b < a) -@test !(b <= a) - -c = BigFloat("24.69135780242") -@test typeof(a * 2) == BigFloat -@test_approx_eq_eps a*2 c tol -@test_approx_eq_eps (c-a) a tol - - -d = BigFloat("-24.69135780242") -@test typeof(d) == BigFloat -@test_approx_eq_eps d+c 0 tol - -#Multiple calls for sanity check, since we're doing direct memory manipulation -@test string(a) == "1.234567890121e+01" -@test string(b) == "1.234567890122e+01" -@test string(c) == "2.469135780242e+01" -@test string(d) == "-2.469135780242e+01" - -@test_approx_eq_eps (BigFloat(3)/BigFloat(2)) BigFloat(1.5) tol - -@test typeof(BigFloat(typemax(Int8))) == BigFloat -@test typeof(BigFloat(typemax(Int16))) == BigFloat -@test typeof(BigFloat(typemax(Int32))) == BigFloat -@test typeof(BigFloat(typemax(Int64))) == BigFloat -#@test typeof(BigFloat(typemax(Int128))) == BigFloat - -@test typeof(BigFloat(true)) == BigFloat -@test typeof(BigFloat(typemax(Uint8))) == BigFloat -@test typeof(BigFloat(typemax(Uint16))) == BigFloat -@test typeof(BigFloat(typemax(Uint32))) == BigFloat -@test typeof(BigFloat(typemax(Uint64))) == BigFloat -#@test typeof(BigFloat(typemax(Uint128))) == BigFloat - -@test typeof(BigFloat(realmax(Float32))) == BigFloat -@test typeof(BigFloat(realmax(Float64))) == BigFloat - -@test typeof(BigFloat(BigInt(1))) == BigFloat -@test typeof(BigFloat(BigFloat(1))) == BigFloat - -@test typeof(BigFloat(1//1)) == BigFloat -@test typeof(BigFloat(one(Rational{BigInt}))) == BigFloat - -f = BigFloat("1234567890.123") -g = BigFloat("1234567891.123") - -tol = 1e-3 - -@test_approx_eq_eps f+int8(1) g tol -@test_approx_eq_eps f+int16(1) g tol -@test_approx_eq_eps f+int32(1) g tol -@test_approx_eq_eps f+int64(1) g tol -#@test_approx_eq_eps f+int128(1) g tol - -@test_approx_eq_eps f+true g tol -@test_approx_eq_eps f+uint8(1) g tol -@test_approx_eq_eps f+uint16(1) g tol -@test_approx_eq_eps f+uint32(1) g tol -@test_approx_eq_eps f+uint64(1) g tol -#@test_approx_eq_eps f+uint128(1) g tol - -@test_approx_eq_eps f+BigInt(1) g tol - -@test_approx_eq_eps f+1f0 g tol -@test_approx_eq_eps f+1e0 g tol - -@test_approx_eq_eps f+BigFloat(1) g tol - -@test_approx_eq_eps f+(1//1) g tol - -@test_approx_eq_eps f+one(Rational{BigInt}) g tol diff --git a/test/mpc.jl b/test/mpc.jl index 9f14192c9b6f0..675463a9bd96e 100644 --- a/test/mpc.jl +++ b/test/mpc.jl @@ -13,8 +13,6 @@ y = MPCComplex(BigInt(12)) @test x == y y = MPCComplex(BigFloat(12)) @test x == y -y = MPCComplex(MPFRFloat(12)) -@test x == y y = MPCComplex("12") @test x == y y = MPCComplex(float32(12.)) @@ -34,8 +32,6 @@ y = MPCComplex(BigInt(12), BigInt(42)) @test x == y y = MPCComplex(BigFloat(12), BigFloat(42)) @test x == y -y = MPCComplex(MPFRFloat(12), MPFRFloat(42)) -@test x == y y = MPCComplex("(12 42)") @test x == y y = MPCComplex(float32(12.), float32(42)) @@ -47,8 +43,8 @@ y = MPCComplex(12 + 42im) # real/imag x = MPCComplex(12, 42) -y = MPFRFloat(12) -z = MPFRFloat(42) +y = BigFloat(12) +z = BigFloat(42) @test real(x) == y @test imag(x) == z y = MPCComplex(x) diff --git a/test/mpfr.jl b/test/mpfr.jl index cc367cf300c48..5a4eb20da27cc 100644 --- a/test/mpfr.jl +++ b/test/mpfr.jl @@ -1,51 +1,51 @@ # constructors with_bigfloat_precision(53) do - x = MPFRFloat() - x = MPFRFloat(12) + x = BigFloat() + x = BigFloat(12) end -x = MPFRFloat(12) -y = MPFRFloat(x) +x = BigFloat(12) +y = BigFloat(x) @test_approx_eq x y -y = MPFRFloat(0xc) +y = BigFloat(0xc) @test_approx_eq x y -y = MPFRFloat(12.) +y = BigFloat(12.) @test_approx_eq x y -y = MPFRFloat(BigInt(12)) +y = BigFloat(BigInt(12)) @test_approx_eq x y -y = MPFRFloat(BigFloat(12)) +y = BigFloat(BigFloat(12)) @test_approx_eq x y -y = MPFRFloat("12") +y = BigFloat("12") @test_approx_eq x y -y = MPFRFloat(float32(12.)) +y = BigFloat(float32(12.)) @test_approx_eq x y -y = MPFRFloat(12//1) +y = BigFloat(12//1) @test_approx_eq x y # + -x = MPFRFloat(12) -y = MPFRFloat(30) -@test x + y == MPFRFloat(42) +x = BigFloat(12) +y = BigFloat(30) +@test x + y == BigFloat(42) # - -x = MPFRFloat(12) -y = MPFRFloat(-30) -@test x - y == MPFRFloat(42) +x = BigFloat(12) +y = BigFloat(-30) +@test x - y == BigFloat(42) # * -x = MPFRFloat(6) -y = MPFRFloat(9) -@test x * y != MPFRFloat(42) -@test x * y == MPFRFloat(54) +x = BigFloat(6) +y = BigFloat(9) +@test x * y != BigFloat(42) +@test x * y == BigFloat(54) # / -x = MPFRFloat(9) -y = MPFRFloat(6) -@test x / y == MPFRFloat(9/6) +x = BigFloat(9) +y = BigFloat(6) +@test x / y == BigFloat(9/6) # < / > / <= / >= -x = MPFRFloat(12) -y = MPFRFloat(42) -z = MPFRFloat(30) +x = BigFloat(12) +y = BigFloat(42) +z = BigFloat(30) @test y > x @test y >= x @test y > z @@ -63,68 +63,68 @@ z = MPFRFloat(30) with_bigfloat_precision(4) do # default mode is round to nearest down, up = with_bigfloat_rounding(MPFR.RoundToNearest) do - MPFRFloat("0.0938"), MPFRFloat("0.102") + BigFloat("0.0938"), BigFloat("0.102") end with_bigfloat_rounding(MPFR.RoundDown) do - @test MPFRFloat(0.1) == down - @test MPFRFloat(0.1) != up + @test BigFloat(0.1) == down + @test BigFloat(0.1) != up end with_bigfloat_rounding(MPFR.RoundUp) do - @test MPFRFloat(0.1) != down - @test MPFRFloat(0.1) == up + @test BigFloat(0.1) != down + @test BigFloat(0.1) == up end end # ^ -x = MPFRFloat(12) -y = MPFRFloat(4) -@test x^y == MPFRFloat(20736) +x = BigFloat(12) +y = BigFloat(4) +@test x^y == BigFloat(20736) # ceil -x = MPFRFloat(12.042) -@test MPFRFloat(13) == ceil(x) +x = BigFloat(12.042) +@test BigFloat(13) == ceil(x) # copysign -x = MPFRFloat(1) -y = MPFRFloat(-1) +x = BigFloat(1) +y = BigFloat(-1) @test copysign(x, y) == y @test copysign(y, x) == x # isfinite / isinf -x = MPFRFloat(Inf) -y = MPFRFloat(1) +x = BigFloat(Inf) +y = BigFloat(1) @test isinf(x) == true @test isinf(y) == false @test isfinite(x) == false @test isinf(x) == true # isnan -x = MPFRFloat(NaN) -y = MPFRFloat(1) +x = BigFloat(NaN) +y = BigFloat(1) @test isnan(x) == true @test isnan(y) == false # convert to -@test convert(MPFRFloat, 1//2) == MPFRFloat("0.5") -@test convert(MPFRFloat, 0.5) == MPFRFloat("0.5") -@test convert(MPFRFloat, 40) == MPFRFloat("40") -@test convert(MPFRFloat, float32(0.5)) == MPFRFloat("0.5") +@test convert(BigFloat, 1//2) == BigFloat("0.5") +@test convert(BigFloat, 0.5) == BigFloat("0.5") +@test convert(BigFloat, 40) == BigFloat("40") +@test convert(BigFloat, float32(0.5)) == BigFloat("0.5") # convert from -@test convert(Float64, MPFRFloat(0.5)) == 0.5 -@test convert(Float32, MPFRFloat(0.5)) == float32(0.5) +@test convert(Float64, BigFloat(0.5)) == 0.5 +@test convert(Float32, BigFloat(0.5)) == float32(0.5) # exponent -x = MPFRFloat(0) +x = BigFloat(0) @test_fails exponent(x) -x = MPFRFloat(Inf) +x = BigFloat(Inf) @test_fails exponent(x) -x = MPFRFloat(15.674) +x = BigFloat(15.674) @test exponent(x) == exponent(15.674) # nextfloat/prevfloat should be immutable x = 12. -y = MPFRFloat(x) +y = BigFloat(x) @test x == y nextfloat(y) @test x == y @@ -132,14 +132,14 @@ prevfloat(y) @test x == y # sqrt DomainError -@test_fails sqrt(MPFRFloat(-1)) +@test_fails sqrt(BigFloat(-1)) # precision old_precision = get_bigfloat_precision() -x = MPFRFloat(0) +x = BigFloat(0) @test get_precision(x) == old_precision set_bigfloat_precision(256) -x = MPFRFloat(0) +x = BigFloat(0) @test get_precision(x) == 256 set_bigfloat_precision(old_precision) z = with_bigfloat_precision(240) do @@ -148,29 +148,29 @@ z = with_bigfloat_precision(240) do end @test float(z) == 20. @test get_precision(z) == 240 -x = MPFRFloat(12) +x = BigFloat(12) @test get_precision(x) == old_precision @test_fails set_bigfloat_precision(1) # integer_valued -@test integer_valued(MPFRFloat(12)) -@test !integer_valued(MPFRFloat(12.12)) +@test integer_valued(BigFloat(12)) +@test !integer_valued(BigFloat(12.12)) # nextfloat / prevfloat with_bigfloat_precision(53) do - x = MPFRFloat(12.12) - @test MPFRFloat(nextfloat(12.12)) == nextfloat(x) - @test MPFRFloat(prevfloat(12.12)) == prevfloat(x) + x = BigFloat(12.12) + @test BigFloat(nextfloat(12.12)) == nextfloat(x) + @test BigFloat(prevfloat(12.12)) == prevfloat(x) end -@test isnan(nextfloat(MPFRFloat(NaN))) -@test isnan(prevfloat(MPFRFloat(NaN))) +@test isnan(nextfloat(BigFloat(NaN))) +@test isnan(prevfloat(BigFloat(NaN))) # comparisons -x = MPFRFloat(1) -y = MPFRFloat(-1) -z = MPFRFloat(NaN) -ipl = MPFRFloat(Inf) -imi = MPFRFloat(-Inf) +x = BigFloat(1) +y = BigFloat(-1) +z = BigFloat(NaN) +ipl = BigFloat(Inf) +imi = BigFloat(-Inf) @test x > y @test x >= y @test x >= x @@ -192,81 +192,81 @@ imi = MPFRFloat(-Inf) @test !(z > z) # modf -x = MPFRFloat(12) -y = MPFRFloat(0.5) +x = BigFloat(12) +y = BigFloat(0.5) @test modf(x+y) == (y, x) -x = MPFRFloat(NaN) +x = BigFloat(NaN) @test map(isnan, modf(x)) == (true, true) -x = MPFRFloat(Inf) +x = BigFloat(Inf) y = modf(x) @test (isnan(y[1]), isinf(y[2])) == (true, true) # rem with_bigfloat_precision(53) do - x = MPFRFloat(2) - y = MPFRFloat(1.67) + x = BigFloat(2) + y = BigFloat(1.67) @test rem(x,y) == rem(2, 1.67) - y = MPFRFloat(NaN) + y = BigFloat(NaN) @test isnan(rem(x,y)) @test isnan(rem(y,x)) - y = MPFRFloat(Inf) + y = BigFloat(Inf) @test rem(x,y) == x @test isnan(rem(y,x)) end # min/max -x = MPFRFloat(4) -y = MPFRFloat(2) +x = BigFloat(4) +y = BigFloat(2) @test max(x,y) == x @test min(x,y) == y -y = MPFRFloat(NaN) +y = BigFloat(NaN) @test max(x,y) == x @test min(x,y) == x @test isnan(max(y,y)) @test isnan(min(y,y)) # sum -x = MPFRFloat(1) -y = MPFRFloat(2) -z = MPFRFloat(3) -w = MPFRFloat(4) -@test sum([x,y,z,w]) == MPFRFloat(10) -big_array = ones(MPFRFloat, 100) -@test sum(big_array) == MPFRFloat(100) +x = BigFloat(1) +y = BigFloat(2) +z = BigFloat(3) +w = BigFloat(4) +@test sum([x,y,z,w]) == BigFloat(10) +big_array = ones(BigFloat, 100) +@test sum(big_array) == BigFloat(100) # promotion # the array converts everyone to the DEFAULT_PRECISION! -x = MPFRFloat(12) +x = BigFloat(12) y = with_bigfloat_precision(60) do - MPFRFloat(42) + BigFloat(42) end -@test [x,y] == [MPFRFloat(12), MPFRFloat(42)] +@test [x,y] == [BigFloat(12), BigFloat(42)] # log / log2 / log10 with_bigfloat_precision(53) do -x = MPFRFloat(42) +x = BigFloat(42) @test log(x) == log(42) - @test isinf(log(MPFRFloat(0))) - @test_fails log(MPFRFloat(-1)) + @test isinf(log(BigFloat(0))) + @test_fails log(BigFloat(-1)) @test log2(x) == log2(42) - @test isinf(log2(MPFRFloat(0))) - @test_fails log2(MPFRFloat(-1)) + @test isinf(log2(BigFloat(0))) + @test_fails log2(BigFloat(-1)) @test log10(x) == log10(42) - @test isinf(log10(MPFRFloat(0))) - @test_fails log10(MPFRFloat(-1)) + @test isinf(log10(BigFloat(0))) + @test_fails log10(BigFloat(-1)) end # exp / exp2 / exp10 with_bigfloat_precision(53) do - x = MPFRFloat(10) + x = BigFloat(10) @test exp(x) == exp(10) @test exp2(x) == 1024 @test exp10(x) == 10000000000 end # convert to integer types -x = MPFRFloat(12.1) -y = MPFRFloat(42) +x = BigFloat(12.1) +y = BigFloat(42) @test_fails convert(Int32, x) @test_fails convert(Int64, x) @test_fails convert(BigInt, x) @@ -279,9 +279,9 @@ y = MPFRFloat(42) @test convert(Uint32, y) == 42 # iround -x = MPFRFloat(42.42) +x = BigFloat(42.42) y = with_bigfloat_precision(256) do - MPFRFloat("9223372036854775809.2324") + BigFloat("9223372036854775809.2324") end z = BigInt("9223372036854775809") @test iround(x) == 42 @@ -296,22 +296,22 @@ z = BigInt("9223372036854775809") # factorial with_bigfloat_precision(256) do - x = MPFRFloat(42) + x = BigFloat(42) @test factorial(x) == factorial(BigInt(42)) - x = MPFRFloat(10) + x = BigFloat(10) @test factorial(x) == factorial(10) - @test_fails factorial(MPFRFloat(-1)) - @test_fails factorial(MPFRFloat(331.3)) + @test_fails factorial(BigFloat(-1)) + @test_fails factorial(BigFloat(331.3)) end # bessel functions with_bigfloat_precision(53) do - @test_approx_eq besselj(4, MPFRFloat(2)) besselj(4, 2.) - @test_approx_eq besselj0(MPFRFloat(2)) besselj0(2.) - @test_approx_eq besselj1(MPFRFloat(2)) besselj1(2.) - @test_approx_eq bessely(4, MPFRFloat(2)) bessely(4, 2.) - @test_approx_eq bessely0(MPFRFloat(2)) bessely0(2.) - @test_approx_eq bessely1(MPFRFloat(2)) bessely1(2.) + @test_approx_eq besselj(4, BigFloat(2)) besselj(4, 2.) + @test_approx_eq besselj0(BigFloat(2)) besselj0(2.) + @test_approx_eq besselj1(BigFloat(2)) besselj1(2.) + @test_approx_eq bessely(4, BigFloat(2)) bessely(4, 2.) + @test_approx_eq bessely0(BigFloat(2)) bessely0(2.) + @test_approx_eq bessely1(BigFloat(2)) bessely1(2.) end # trigonometric functions @@ -320,49 +320,49 @@ with_bigfloat_precision(53) do :cosh,:sinh,:tanh,:sech,:csch,:coth,:asinh), j in (-1., -0.5, -0.25, .25, .5, 1.) @eval begin - @test_approx_eq ($f)(MPFRFloat($j)) ($f)($j) + @test_approx_eq ($f)(BigFloat($j)) ($f)($j) end end for f in (:acos,:asin,:acosh,:atanh), j in (-2, -1.5) @eval begin - @test_fails ($f)(MPFRFloat($j)) + @test_fails ($f)(BigFloat($j)) end end for f in (:sin,:cos,:tan,:sec,:csc,:cot,:cosh,:sinh,:tanh, :sech,:csch,:coth,:acosh,:asinh), j in (1., 1.5, 1.9) @eval begin - @test_approx_eq ($f)(MPFRFloat($j)) ($f)($j) + @test_approx_eq ($f)(BigFloat($j)) ($f)($j) end end for j in (.25, .5) - @test_approx_eq atanh(MPFRFloat(j)) atanh(j) + @test_approx_eq atanh(BigFloat(j)) atanh(j) end end # hypot -@test hypot(MPFRFloat(3), MPFRFloat(4)) == 5 +@test hypot(BigFloat(3), BigFloat(4)) == 5 # atan2 with_bigfloat_precision(53) do - @test isequal(atan2(12,2), atan2(MPFRFloat(12), MPFRFloat(2))) + @test isequal(atan2(12,2), atan2(BigFloat(12), BigFloat(2))) end # ldexp with_bigfloat_precision(53) do - @test ldexp(MPFRFloat(24.5), 72) == ldexp(24.5, 72) - @test ldexp(MPFRFloat(24.5), int16(72)) == ldexp(24.5, 72) - @test ldexp(MPFRFloat(24.5), -72) == ldexp(24.5, -72) - @test ldexp(MPFRFloat(24.5), int16(-72)) == ldexp(24.5, -72) - @test ldexp(MPFRFloat(24.5), uint(72)) == ldexp(24.5, 72) - @test ldexp(MPFRFloat(24.5), 0x48) == ldexp(24.5, 72) + @test ldexp(BigFloat(24.5), 72) == ldexp(24.5, 72) + @test ldexp(BigFloat(24.5), int16(72)) == ldexp(24.5, 72) + @test ldexp(BigFloat(24.5), -72) == ldexp(24.5, -72) + @test ldexp(BigFloat(24.5), int16(-72)) == ldexp(24.5, -72) + @test ldexp(BigFloat(24.5), uint(72)) == ldexp(24.5, 72) + @test ldexp(BigFloat(24.5), 0x48) == ldexp(24.5, 72) end # basic arithmetic # Signed addition -a = MPFRFloat("123456789012345678901234567890") -b = MPFRFloat("123456789012345678901234567891") +a = BigFloat("123456789012345678901234567890") +b = BigFloat("123456789012345678901234567891") @test a+int8(1) == b @test a+int16(1) == b @test a+int32(1) == b @@ -485,8 +485,8 @@ b = MPFRFloat("123456789012345678901234567891") # Signed division c = BigInt("61728394506172839450617283945") # d = 2^200 -d = MPFRFloat("1606938044258990275541962092341162602522202993782792835301376") -f = MPFRFloat("6.223015277861141707144064053780124240590252168721167133101116614789698834035383e-61") +d = BigFloat("1606938044258990275541962092341162602522202993782792835301376") +f = BigFloat("6.223015277861141707144064053780124240590252168721167133101116614789698834035383e-61") @test a/int8(2) == c @test a/int16(2) == c @@ -525,3 +525,82 @@ f = MPFRFloat("6.223015277861141707144064053780124240590252168721167133101116614 # BigInt division @test a / BigInt(2) == c + +# old tests +tol = 1e-12 + +a = BigFloat("12.34567890121") +b = BigFloat("12.34567890122") + +@test_approx_eq_eps a+1e-11 b tol +@test !(b == a) +@test b > a +@test b >= a +@test !(b < a) +@test !(b <= a) + +c = BigFloat("24.69135780242") +@test typeof(a * 2) == BigFloat +@test_approx_eq_eps a*2 c tol +@test_approx_eq_eps (c-a) a tol + + +d = BigFloat("-24.69135780242") +@test typeof(d) == BigFloat +@test_approx_eq_eps d+c 0 tol + +@test_approx_eq_eps (BigFloat(3)/BigFloat(2)) BigFloat(1.5) tol + +@test typeof(BigFloat(typemax(Int8))) == BigFloat +@test typeof(BigFloat(typemax(Int16))) == BigFloat +@test typeof(BigFloat(typemax(Int32))) == BigFloat +@test typeof(BigFloat(typemax(Int64))) == BigFloat +#@test typeof(BigFloat(typemax(Int128))) == BigFloat + +@test typeof(BigFloat(true)) == BigFloat +@test typeof(BigFloat(typemax(Uint8))) == BigFloat +@test typeof(BigFloat(typemax(Uint16))) == BigFloat +@test typeof(BigFloat(typemax(Uint32))) == BigFloat +@test typeof(BigFloat(typemax(Uint64))) == BigFloat +#@test typeof(BigFloat(typemax(Uint128))) == BigFloat + +@test typeof(BigFloat(realmax(Float32))) == BigFloat +@test typeof(BigFloat(realmax(Float64))) == BigFloat + +@test typeof(BigFloat(BigInt(1))) == BigFloat +@test typeof(BigFloat(BigFloat(1))) == BigFloat + +@test typeof(BigFloat(1//1)) == BigFloat +@test typeof(BigFloat(one(Rational{BigInt}))) == BigFloat + +f = BigFloat("1234567890.123") +g = BigFloat("1234567891.123") + +tol = 1e-3 + +@test_approx_eq_eps f+int8(1) g tol +@test_approx_eq_eps f+int16(1) g tol +@test_approx_eq_eps f+int32(1) g tol +@test_approx_eq_eps f+int64(1) g tol +#@test_approx_eq_eps f+int128(1) g tol + +@test_approx_eq_eps f+true g tol +@test_approx_eq_eps f+uint8(1) g tol +@test_approx_eq_eps f+uint16(1) g tol +@test_approx_eq_eps f+uint32(1) g tol +@test_approx_eq_eps f+uint64(1) g tol +#@test_approx_eq_eps f+uint128(1) g tol + +@test_approx_eq_eps f+BigInt(1) g tol + +@test_approx_eq_eps f+1f0 g tol +@test_approx_eq_eps f+1e0 g tol + +@test_approx_eq_eps f+BigFloat(1) g tol + +@test_approx_eq_eps f+(1//1) g tol + +@test_approx_eq_eps f+one(Rational{BigInt}) g tol + +# new tests + diff --git a/test/runtests.jl b/test/runtests.jl index 96b0c7d4cb307..ec86b2b63fffe 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,7 +3,7 @@ testnames = ["core", "keywordargs", "numbers", "strings", "unicode", "linalg", "blas", "fft", "dsp", "sparse", "bitarray", "random", "math", "functional", "bigint", "sorting", "statistics", "spawn", "parallel", "priorityqueue", - "arpack", "bigfloat", "file", "perf", "suitesparse", "version", + "arpack", "file", "perf", "suitesparse", "version", "pollfd", "mpfr", "mpc"] # Disabled: "complex" From 728a1f558b5f18b457a5ee7e2929d830f12b0740 Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Fri, 3 May 2013 05:18:56 -0300 Subject: [PATCH 30/31] Remove all mentions to MPC, as it was decided to scrap it Now BigComplex support is given directly through Complex{BigFloat}. --- .travis.yml | 4 +- LICENSE.md | 1 - Make.inc | 1 - Makefile | 2 +- README.md | 2 - base/exports.jl | 5 - base/mpc.jl | 310 ------------------ base/sysimg.jl | 2 - deps/.gitignore | 1 - deps/Makefile | 46 +-- test/mpc.jl | 816 ----------------------------------------------- test/runtests.jl | 2 +- 12 files changed, 6 insertions(+), 1186 deletions(-) delete mode 100644 base/mpc.jl delete mode 100644 test/mpc.jl diff --git a/.travis.yml b/.travis.yml index 66fe42985df6c..e3c4e6620dd0d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,12 +5,12 @@ compiler: notifications: email: false before_install: - - BUILDOPTS="LLVM_CONFIG=llvm-config-3.2 USE_QUIET=0 USE_LIB64=0"; for lib in LLVM ZLIB SUITESPARSE ARPACK BLAS FFTW LAPACK GMP MPFR MPC PCRE LIBUNWIND READLINE GRISU OPENLIBM RMATH LIBUV; do export BUILDOPTS="$BUILDOPTS USE_SYSTEM_$lib=1"; done + - BUILDOPTS="LLVM_CONFIG=llvm-config-3.2 USE_QUIET=0 USE_LIB64=0"; for lib in LLVM ZLIB SUITESPARSE ARPACK BLAS FFTW LAPACK GMP MPFR PCRE LIBUNWIND READLINE GRISU OPENLIBM RMATH LIBUV; do export BUILDOPTS="$BUILDOPTS USE_SYSTEM_$lib=1"; done - sudo apt-get update -qq -y - sudo apt-get install zlib1g-dev - sudo add-apt-repository ppa:staticfloat/julia-deps -y - sudo apt-get update -qq -y - - sudo apt-get install patchelf gfortran llvm-3.2-dev libsuitesparse-dev libncurses5-dev libopenblas-dev liblapack-dev libarpack2-dev libfftw3-dev libgmp-dev libpcre3-dev libunwind7-dev libreadline-dev libdouble-conversion-dev libopenlibm-dev librmath-dev libuv-julia-dev libmpfr-dev libmpc-dev -y + - sudo apt-get install patchelf gfortran llvm-3.2-dev libsuitesparse-dev libncurses5-dev libopenblas-dev liblapack-dev libarpack2-dev libfftw3-dev libgmp-dev libpcre3-dev libunwind7-dev libreadline-dev libdouble-conversion-dev libopenlibm-dev librmath-dev libuv-julia-dev libmpfr-dev -y script: - make $BUILDOPTS PREFIX=/tmp/julia install - cd .. && mv julia julia2 diff --git a/LICENSE.md b/LICENSE.md index b574e102095ab..fb06837f22f72 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -58,7 +58,6 @@ External libraries, if used, include their own licenses: - [LAPACK](http://netlib.org/lapack/LICENSE.txt) - [LIBUNWIND](http://git.savannah.gnu.org/gitweb/?p=libunwind.git;a=blob_plain;f=LICENSE;hb=master) - [LLVM](http://llvm.org/releases/3.0/LICENSE.TXT) -- [MPC](http://www.multiprecision.org/index.php?prog=mpc&page=html#Copying) - [MPFR](http://www.mpfr.org/mpfr-current/mpfr.html#Copying) - [OPENBLAS](https://raw.github.com/xianyi/OpenBLAS/master/LICENSE) - [PCRE](http://www.pcre.org/licence.txt) diff --git a/Make.inc b/Make.inc index cf5c3396d9dd8..99c380f50ab19 100644 --- a/Make.inc +++ b/Make.inc @@ -164,7 +164,6 @@ USE_SYSTEM_LAPACK=0 USE_SYSTEM_FFTW=0 USE_SYSTEM_GMP=0 USE_SYSTEM_MPFR=0 -USE_SYSTEM_MPC=0 USE_SYSTEM_ARPACK=0 USE_SYSTEM_SUITESPARSE=0 USE_SYSTEM_ZLIB=0 diff --git a/Makefile b/Makefile index 738a27db34173..b5b4bd7c39c3c 100644 --- a/Makefile +++ b/Makefile @@ -66,7 +66,7 @@ JL_PRIVATE_LIBS = amd arpack camd ccolamd cholmod colamd \ fftw3 fftw3f fftw3_threads fftw3f_threads \ gmp grisu openlibm openlibm-extras pcre \ random Rmath spqr suitesparse_wrapper \ - umfpack z openblas mpfr mpc + umfpack z openblas mpfr PREFIX ?= julia-$(JULIA_COMMIT) install: diff --git a/README.md b/README.md index f1fd88df41360..19a6dba48f3a0 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,6 @@ Julia uses the following external libraries, which are automatically downloaded - **[PCRE]** — Perl-compatible regular expressions library. - **[GMP]** — the GNU multiple precision arithmetic library, needed for bigint support. - **[MPFR]** — the GNU multiple precision floating point library, needed for arbitrary precision floating point support. -- **[MPC]** — the GNU multiple precision complex arithmetic library, needed for arbitrary precision complex number support. - **[double-conversion]** — efficient number-to-text conversion. - **[Rmath]** — basic RNGs and distributions. @@ -182,7 +181,6 @@ Julia uses the following external libraries, which are automatically downloaded [readline]: http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html [GMP]: http://gmplib.org/ [MPFR]: http://www.mpfr.org/ -[MPC]: http://www.multiprecision.org/ [double-conversion]: http://double-conversion.googlecode.com/ [Rmath]: http://cran.r-project.org/doc/manuals/R-admin.html#The-standalone-Rmath-library [libuv]: https://github.com/JuliaLang/libuv diff --git a/base/exports.jl b/base/exports.jl index b29ca955dd664..5194645f31f43 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -9,7 +9,6 @@ export LibRandom, Random, Math, - MPC, MPFR, GMP, Sort, @@ -58,7 +57,6 @@ export IntSet, LocalProcess, Matrix, - MPCComplex, ObjectIdDict, #Pipe, #PipeEnd, @@ -827,11 +825,8 @@ export exp10, get_precision, get_bigfloat_precision, - get_bigcomplex_precision, set_bigfloat_precision, - set_bigcomplex_precision, with_bigfloat_precision, - with_bigcomplex_precision, get_bigfloat_rounding, set_bigfloat_rounding, with_bigfloat_rounding, diff --git a/base/mpc.jl b/base/mpc.jl deleted file mode 100644 index 544bcec508f72..0000000000000 --- a/base/mpc.jl +++ /dev/null @@ -1,310 +0,0 @@ -module MPC - -export - # Types - MPCComplex, - # Functions - get_bigcomplex_precision, - set_bigcomplex_precision, - with_bigcomplex_precision - -import - Base: (*), +, -, /, <, <<, >>, <=, ==, >, >=, ^, (~), (&), (|), ($), cmp, - complex, conj, convert, div, exp, imag, integer_valued, isfinite, - isinf, log, promote_rule, real, show, showcompact, sqrt, string, - get_precision, - - # trigonometric functions - sin, cos, tan, acos, asin, atan, cosh, sinh, tanh, acosh, asinh, atanh - -const ROUNDING_MODE = [0] -const DEFAULT_PRECISION = [256, 256] - -# Basic type and initialization definitions - -type MPCComplex <: Number - # Real MPFR part - reprec::Clong - resign::Cint - reexp::Clong - red::Ptr{Void} - # Imaginary MPFR part - imprec::Clong - imsign::Cint - imexp::Clong - imd::Ptr{Void} - function MPCComplex() - N, P = get_bigcomplex_precision() - z = new(convert(Clong, 0), convert(Cint, 0), convert(Clong, 0), - C_NULL, convert(Clong, 0), convert(Cint, 0), convert(Clong, 0), C_NULL) - ccall((:mpc_init3,:libmpc), Void, (Ptr{MPCComplex}, Clong, Clong), &z, N, P) - finalizer(z, MPC_clear) - return z - end -end - -MPC_clear(mpc::MPCComplex) = ccall((:mpc_clear, :libmpc), Void, (Ptr{MPCComplex},), &mpc) - -MPCComplex(x::MPCComplex) = x - -# Real constructors -for (fJ, fC) in ((:si,:Int), (:ui,:Uint), (:d,:Float64)) - @eval begin - function MPCComplex(x::($fC)) - z = MPCComplex() - ccall(($(string(:mpc_set_,fJ)), :libmpc), Int32, (Ptr{MPCComplex}, ($fC), Int32), &z, x, ROUNDING_MODE[end]) - return z - end - end -end - -function MPCComplex(x::BigInt) - z = MPCComplex() - ccall((:mpc_set_z, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{BigInt}, Int32), &z, &x, ROUNDING_MODE[end]) - return z -end - -function MPCComplex(x::BigFloat) - z = MPCComplex() - ccall((:mpc_set_fr, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{BigFloat}, Int32), &z, &x, ROUNDING_MODE[end]) - return z -end - -function MPCComplex(x::String, base::Int) - z = MPCComplex() - err = ccall((:mpc_set_str, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{Uint8}, Int32, Int32), &z, x, base, ROUNDING_MODE[end]) - if err != 0; error("Invalid input"); end - return z -end -MPCComplex(x::String) = MPCComplex(x, 10) - -MPCComplex(x::Bool) = MPCComplex(uint(x)) -MPCComplex(x::Signed) = MPCComplex(int(x)) -MPCComplex(x::Unsigned) = MPCComplex(uint(x)) -if WORD_SIZE == 32 - MPCComplex(x::Int64) = MPCComplex(BigInt(x)) - MPCComplex(x::Uint64) = MPCComplex(BigInt(x)) -end -MPCComplex(x::Float32) = MPCComplex(float64(x)) -MPCComplex(x::Rational) = MPCComplex(num(x)) / MPCComplex(den(x)) - -convert(::Type{MPCComplex}, x::Rational) = MPCComplex(x) # to resolve ambiguity -convert(::Type{MPCComplex}, x::Real) = MPCComplex(x) -convert(::Type{MPCComplex}, x::Complex) = MPCComplex(x) -convert(::Type{MPCComplex}, x::ImaginaryUnit) = MPCComplex(x) - -function convert(::Type{Complex{Float64}}, x::MPCComplex) - return complex( - ccall((:mpfr_get_d,:libmpfr), Float64, (Ptr{Void},), &(realref(x))), - ccall((:mpfr_get_d,:libmpfr), Float64, (Ptr{Void},), &(imagref(x)))) -end -function convert(::Type{Complex{Float32}}, x::MPCComplex) - return complex( - ccall((:mpfr_get_flt,:libmpfr), Float32, (Ptr{Void},), &(realref(x))), - ccall((:mpfr_get_flt,:libmpfr), Float32, (Ptr{Void},), &(imagref(x)))) -end -function convert(::Type{Complex{Int64}}, x::MPCComplex) - if realint(x) && imagint(x) - return complex( - ccall((:mpfr_get_si,:libmpfr), Int64, (Ptr{Void}, Int32), &(realref(x)), ROUNDING_MODE[end]), - ccall((:mpfr_get_si,:libmpfr), Int64, (Ptr{Void}, Int32), &(imagref(x)), ROUNDING_MODE[end])) - else - throw(InexactError()) - end -end -function convert(::Type{Complex{Int32}}, x::MPCComplex) - if realint(x) && imagint(x) - return complex( - int32(ccall((:mpfr_get_si,:libmpfr), Int64, (Ptr{Void}, Int32), &(realref(x)), ROUNDING_MODE[end])), - int32(ccall((:mpfr_get_si,:libmpfr), Int64, (Ptr{Void}, Int32), &(imagref(x)), ROUNDING_MODE[end]))) - else - throw(InexactError()) - end -end -promote_rule{T<:Real}(::Type{MPCComplex}, ::Type{T}) = MPCComplex -promote_rule{T<:Real}(::Type{MPCComplex}, ::Type{Complex{T}}) = MPCComplex -promote_rule{T<:Number}(::Type{MPCComplex}, ::Type{T}) = MPCComplex -promote_rule(::Type{MPCComplex}, ::Type{ImaginaryUnit}) = MPCComplex - -# Complex constructors -for (fJ, fC) in ((:si,:Int), (:ui,:Uint), (:d,:Float64)) - @eval begin - function MPCComplex(x::($fC), y::($fC)) - z = MPCComplex() - ccall(($(string(:mpc_set_,fJ,'_',fJ)), :libmpc), Int32, (Ptr{MPCComplex}, ($fC), ($fC), Int32), &z, x, y, ROUNDING_MODE[end]) - return z - end - end -end - -function MPCComplex(x::BigInt, y::BigInt) - z = MPCComplex() - ccall((:mpc_set_z_z, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{BigInt}, Ptr{BigInt}, Int32), &z, &x, &y, ROUNDING_MODE[end]) - return z -end - -function MPCComplex(x::BigFloat, y::BigFloat) - z = MPCComplex() - ccall((:mpc_set_fr_fr, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{BigFloat}, Ptr{BigFloat}, Int32), &z, &x, &y, ROUNDING_MODE[end]) - return z -end - -MPCComplex(x::Complex) = MPCComplex(real(x), imag(x)) -MPCComplex(x::ImaginaryUnit) = MPCComplex(1im) -MPCComplex(x::Bool, y::Bool) = MPCComplex(uint(x), uint(y)) -MPCComplex(x::Signed, y::Signed) = MPCComplex(int(x), int(y)) -MPCComplex(x::Unsigned, y::Unsigned) = MPCComplex(uint(x), uint(y)) -if WORD_SIZE == 32 - MPCComplex(x::Int64, y::Int64) = MPCComplex(BigInt(x), BigInt(y)) - MPCComplex(x::Uint64, y::Uint64) = MPCComplex(BigInt(x), BigInt(y)) -end -MPCComplex(x::Float32, y::Float32) = MPCComplex(float64(x), float64(y)) -MPCComplex(x::Rational, y::Rational) = MPCComplex(BigFloat(num(x))/BigFloat(den(x)), - BigFloat(num(y))/BigFloat(den(y))) - -# Basic operations - -for (fJ, fC) in ((:+,:add), (:-,:sub), (:*,:mul), (:/,:div), (:^, :pow)) - @eval begin - function ($fJ)(x::MPCComplex, y::MPCComplex) - z = MPCComplex() - ccall(($(string(:mpc_,fC)),:libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Ptr{MPCComplex}, Int32), &z, &x, &y, ROUNDING_MODE[end]) - return z - end - end -end - -function -(x::MPCComplex) - z = MPCComplex() - ccall((:mpc_neg, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) - return z -end - -function cmp(x::MPCComplex, y::MPCComplex) - ccall((:mpc_cmp, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}), &x, &y) -end - -function sqrt(x::MPCComplex) - z = MPCComplex() - ccall((:mpc_sqrt, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) - return z -end - -function ^(x::MPCComplex, y::Uint) - z = MPCComplex() - ccall((:mpc_pow_ui, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Uint, Int32), &z, &x, y, ROUNDING_MODE[end]) - return z -end - -function ^(x::MPCComplex, y::Int) - z = MPCComplex() - ccall((:mpc_pow_si, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Int, Int32), &z, &x, y, ROUNDING_MODE[end]) - return z -end - -function ^(x::MPCComplex, y::BigInt) - z = MPCComplex() - ccall((:mpc_pow_z, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Ptr{BigInt}, Int32), &z, &x, &y, ROUNDING_MODE[end]) - return z -end - -function exp(x::MPCComplex) - z = MPCComplex() - ccall((:mpc_exp, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) - return z -end - -function log(x::MPCComplex) - z = MPCComplex() - ccall((:mpc_log, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) - return z -end - -# Trigonometric functions -# No error handling is done, and NaN are returned directly -# the Base functions behavior -for f in (:sin,:cos,:tan,:acos,:asin,:atan, - :cosh,:sinh,:tanh,:acosh,:asinh,:atanh) - @eval begin - function ($f)(x::MPCComplex) - z = MPCComplex() - ccall(($(string(:mpc_,f)), :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) - return z - end - end -end - -# Utility functions -==(x::MPCComplex, y::MPCComplex) = ccall((:mpc_cmp, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}), &x, &y) == 0 - -function get_precision(x::MPCComplex) - a = [0] - b = [0] - ccall((:mpc_get_prec2, :libmpc), Int, (Ptr{Int}, Ptr{Int}, Ptr{MPCComplex}), a, b, &x) - return (a[1],b[1]) -end - -get_bigcomplex_precision() = (DEFAULT_PRECISION[1],DEFAULT_PRECISION[end]) -function set_bigcomplex_precision(x::Int, y::Int) - if x < 2 - throw(DomainError()) - end - DEFAULT_PRECISION[1], DEFAULT_PRECISION[end] = x, y -end -set_bigcomplex_precision(x::(Int,Int)) = set_bigcomplex_precision(x...) - -isfinite(x::MPCComplex) = isfinite(real(x)) && isfinite(imag(x)) -isinf(x::MPCComplex) = !isfinite(x) -integer_valued(x::MPCComplex) = imag(x) == 0 && integer_valued(real(x)) - -function with_bigcomplex_precision(f::Function, realprec::Integer, imagprec::Integer) - old_precision = get_bigcomplex_precision() - set_bigcomplex_precision(realprec, imagprec) - ret = f() - set_bigcomplex_precision(old_precision) - return ret -end -with_bigcomplex_precision(f::Function, prec::Integer) = with_bigcomplex_precision(f, prec, prec) - -function imag(x::MPCComplex) - z = with_bigfloat_precision(get_bigcomplex_precision()[end]) do - BigFloat() - end - ccall((:mpc_imag, :libmpc), Int32, (Ptr{BigFloat}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) - return z -end - -function real(x::MPCComplex) - z = with_bigfloat_precision(get_bigcomplex_precision()[1]) do - BigFloat() - end - ccall((:mpc_real, :libmpc), Int32, (Ptr{BigFloat}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) - return z -end - -function conj(x::MPCComplex) - z = MPCComplex() - ccall((:mpc_conj, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) - return z -end - -string(x::MPCComplex) = "$(string(real(x))) + $(string(imag(x)))im" - -show(io::IO, b::MPCComplex) = print(io, string(b) * " with $(get_precision(b)) bits of precision") -showcompact(io::IO, b::MPCComplex) = print(io, string(b)) - -function copy(x::MPCComplex) - z = MPCComplex() - ccall((:mpc_set, :libmpc), Int32, (Ptr{MPCComplex}, Ptr{MPCComplex}, Int32), &z, &x, ROUNDING_MODE[end]) - return z -end - -# Internal functions -# Unsafe for general use -realref(x::MPCComplex) = BigFloat(x.reprec, x.resign, x.reexp, x.red) -imagref(x::MPCComplex) = BigFloat(x.imprec, x.imsign, x.imexp, x.imd) -realint(x::MPCComplex) = ccall((:mpfr_integer_p, :libmpfr), Int32, (Ptr{Void},), &(realref(x))) != 0 -imagint(x::MPCComplex) = ccall((:mpfr_integer_p, :libmpfr), Int32, (Ptr{Void},), &(imagref(x))) != 0 - - -end #module diff --git a/base/sysimg.jl b/base/sysimg.jl index 9ba66f78f0b3a..25e4a21bc3577 100644 --- a/base/sysimg.jl +++ b/base/sysimg.jl @@ -174,8 +174,6 @@ include("gmp.jl") importall .GMP include("mpfr.jl") importall .MPFR -include("mpc.jl") -importall .MPC # deprecated functions include("deprecated.jl") diff --git a/deps/.gitignore b/deps/.gitignore index 1957599abeaa6..86ee7cfaca893 100644 --- a/deps/.gitignore +++ b/deps/.gitignore @@ -15,7 +15,6 @@ /libunwind-* /lighttpd-* /llvm-* -/mpc-* /mpfr-* /openblas-* /patchelf-* diff --git a/deps/Makefile b/deps/Makefile index 1f8450fe9adf4..493dcdfc78d7c 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -21,7 +21,7 @@ ifeq ($(OS),WINNT) CONFIGURE_COMMON += LDFLAGS=-Wl,--stack,8388608 endif -#autoconf configure-driven scripts: llvm readline pcre arpack fftw unwind gmp mpfr mpc patchelf +#autoconf configure-driven scripts: llvm readline pcre arpack fftw unwind gmp mpfr patchelf #custom configure-driven script: zlib #custom Makefile rules: openlibm Rmath double-conversion random suitesparse-wrapper suitesparse lapack openblas uv @@ -106,10 +106,6 @@ ifeq ($(USE_SYSTEM_MPFR), 0) STAGE1_DEPS += mpfr endif -ifeq ($(USE_SYSTEM_MPC), 0) -STAGE1_DEPS += mpc -endif - ifeq ($(USE_SYSTEM_ARPACK), 0) STAGE2_DEPS += arpack endif @@ -142,7 +138,7 @@ install: $(addprefix install-, $(LIBS)) cleanall: $(addprefix clean-, $(LIBS)) distclean: $(addprefix distclean-, $(LIBS)) rm -rf $(BUILD) -getall: get-llvm get-readline get-uv get-pcre get-double-conversion get-openlibm get-random get-openblas get-fftw get-suitesparse get-unwind get-gmp get-mpfr get-mpc get-zlib get-patchelf +getall: get-llvm get-readline get-uv get-pcre get-double-conversion get-openlibm get-random get-openblas get-fftw get-suitesparse get-unwind get-gmp get-mpfr get-zlib get-patchelf ## PATHS ## DIRS = $(addprefix $(BUILD)/,lib include bin share etc) @@ -1228,44 +1224,6 @@ compile-mpfr: $(MPFR_SRC_TARGET) check-mpfr: mpfr-$(MPFR_VER)/checked install-mpfr: $(MPFR_OBJ_TARGET) -## MPC ## - -MPC_SRC_TARGET = mpc-$(MPC_VER)/.libs/libmpc.$(SHLIB_EXT) -MPC_OBJ_TARGET = $(BUILD)/lib/libmpc.$(SHLIB_EXT) - -mpc-$(MPC_VER).tar.gz: - $(WGET_DASH_O) $@ http://www.multiprecision.org/mpc/download/$@ -mpc-$(MPC_VER)/configure: mpc-$(MPC_VER).tar.gz - tar zxf $< - touch -c $@ -mpc-$(MPC_VER)/config.status: mpc-$(MPC_VER)/configure - cd mpc-$(MPC_VER) && \ - ./configure $(CONFIGURE_COMMON) F77= --enable-shared --disable-static - touch -c $@ -$(MPC_SRC_TARGET): mpc-$(MPC_VER)/config.status - $(MAKE) -C mpc-$(MPC_VER) $(LIBTOOL_CCLD) -mpc-$(MPC_VER)/checked: $(MPC_SRC_TARGET) -ifeq ($(OS),$(BUILD_OS)) - $(MAKE) -C mpc-$(MPC_VER) $(LIBTOOL_CCLD) check -endif - echo 1 > $@ -$(MPC_OBJ_TARGET): $(MPC_SRC_TARGET) mpc-$(MPC_VER)/checked - $(MAKE) -C mpc-$(MPC_VER) $(LIBTOOL_CCLD) install - $(INSTALL_NAME_CMD)libmpc.dylib $@ - touch -c $@ - -clean-mpc: - -$(MAKE) -C mpc-$(MPC_VER) clean - -rm -f $(MPC_OBJ_TARGET) -distclean-mpc: - -rm -rf mpc-$(MPC_VER).tar.gz mpc-$(MPC_VER) - -get-mpc: mpc-$(MPC_VER).tar.gz -configure-mpc: mpc-$(MPC_VER)/config.status -compile-mpc: $(MPC_SRC_TARGET) -check-mpc: mpc-$(MPC_VER)/checked -install-mpc: $(MPC_OBJ_TARGET) - ## ZLIB ## ifeq ($(OS),WINNT) diff --git a/test/mpc.jl b/test/mpc.jl deleted file mode 100644 index 675463a9bd96e..0000000000000 --- a/test/mpc.jl +++ /dev/null @@ -1,816 +0,0 @@ -# real constructors -with_bigcomplex_precision(53,53) do - x = MPCComplex() -end -x = MPCComplex(12) -y = MPCComplex(x) -@test x == y -y = MPCComplex(0xc) -@test x == y -y = MPCComplex(12.) -@test x == y -y = MPCComplex(BigInt(12)) -@test x == y -y = MPCComplex(BigFloat(12)) -@test x == y -y = MPCComplex("12") -@test x == y -y = MPCComplex(float32(12.)) -@test x == y -y = MPCComplex(12//1) -@test x == y - -# complex constructors -x = MPCComplex(12, 42) -y = MPCComplex(x) -@test x == y -y = MPCComplex(0xc, 0x2a) -@test x == y -y = MPCComplex(12., 42.) -@test x == y -y = MPCComplex(BigInt(12), BigInt(42)) -@test x == y -y = MPCComplex(BigFloat(12), BigFloat(42)) -@test x == y -y = MPCComplex("(12 42)") -@test x == y -y = MPCComplex(float32(12.), float32(42)) -@test x == y -y = MPCComplex(12//1, 42//1) -@test x == y -y = MPCComplex(12 + 42im) -@test x == y - -# real/imag -x = MPCComplex(12, 42) -y = BigFloat(12) -z = BigFloat(42) -@test real(x) == y -@test imag(x) == z -y = MPCComplex(x) -@test real(x) == real(y) -@test imag(x) == imag(y) - -# conversion -with_bigcomplex_precision(53) do - x = MPCComplex(12, 42) - @test typeof(convert(Complex{Float64}, x)) == Complex{Float64} - @test typeof(convert(Complex{Float32}, x)) == Complex{Float32} - @test typeof(convert(Complex{Int64}, x)) == Complex{Int64} - @test typeof(convert(Complex{Int32}, x)) == Complex{Int32} - @test 12. + 42.0im == convert(Complex{Float64}, x) - @test 12f0 + 42f0im == convert(Complex{Float32}, x) - @test 12 + 42im == convert(Complex{Int64}, x) - @test 12 + 42im == convert(Complex{Int32}, x) -end - -# + -x = MPCComplex(12,42) -@test (x + x) == MPCComplex(24, 84) -@test (x + 2) == MPCComplex(14, 42) -@test (x + (2+ 1im)) == MPCComplex(14, 43) -@test (x + 2 + 1im) == MPCComplex(14, 43) - -# integer_valued -@test !integer_valued(MPCComplex(2,3)) -@test integer_valued(MPCComplex(2)) - -# conj -@test isequal(conj(MPCComplex(2,1)), MPCComplex(2,-1)) -@test isequal(conj(MPCComplex(2.,NaN)), MPCComplex(2.,NaN)) -@test isequal(conj(MPCComplex(2.,Inf)), MPCComplex(2.,-Inf)) -@test isequal(conj(MPCComplex(2.,-Inf)), MPCComplex(2.,Inf)) - -# Kahan tests from #2845 by @simonbyrne -with_bigcomplex_precision(53,53) do -# sqrt: -# tests special values from csqrt man page -# as well as conj(sqrt(z)) = sqrt(conj(z)) -@test isequal(sqrt(MPCComplex(0.0,0.0)), MPCComplex(0.0,0.0)) -@test isequal(sqrt(MPCComplex(-0.0,0.0)), MPCComplex(0.0,0.0)) -@test isequal(sqrt(MPCComplex(0.0,-0.0)), MPCComplex(0.0,-0.0)) -@test isequal(sqrt(MPCComplex(-0.0,-0.0)), MPCComplex(0.0,-0.0)) - -@test isequal(sqrt(MPCComplex(5.0,0.0)), MPCComplex(sqrt(5.0),0.0)) -@test isequal(sqrt(MPCComplex(5.0,-0.0)), MPCComplex(sqrt(5.0),-0.0)) - -@test isequal(sqrt(MPCComplex(-5.0,0.0)), MPCComplex(0.0,sqrt(5.0))) -@test isequal(sqrt(MPCComplex(-5.0,-0.0)), MPCComplex(0.0,-sqrt(5.0))) - -@test isequal(sqrt(MPCComplex(0.0,Inf)), MPCComplex(Inf,Inf)) -@test isequal(sqrt(MPCComplex(0.0,-Inf)), MPCComplex(Inf,-Inf)) - -@test isequal(sqrt(MPCComplex(NaN,Inf)), MPCComplex(Inf,Inf)) -@test isequal(sqrt(MPCComplex(NaN,-Inf)), MPCComplex(Inf,-Inf)) - -@test isequal(sqrt(MPCComplex(Inf,Inf)), MPCComplex(Inf,Inf)) -@test isequal(sqrt(MPCComplex(Inf,-Inf)), MPCComplex(Inf,-Inf)) -@test isequal(sqrt(MPCComplex(-Inf,Inf)), MPCComplex(Inf,Inf)) -@test isequal(sqrt(MPCComplex(-Inf,-Inf)), MPCComplex(Inf,-Inf)) - -@test isequal(sqrt(MPCComplex(0.0,NaN)), MPCComplex(NaN,NaN)) - -@test isequal(sqrt(MPCComplex(-Inf,0.0)), MPCComplex(0.0,Inf)) -@test isequal(sqrt(MPCComplex(-Inf,5.0)), MPCComplex(0.0,Inf)) -@test isequal(sqrt(MPCComplex(-Inf,-0.0)), MPCComplex(0.0,-Inf)) -@test isequal(sqrt(MPCComplex(-Inf,-5.0)), MPCComplex(0.0,-Inf)) - -@test isequal(sqrt(MPCComplex(Inf,0.0)), MPCComplex(Inf,0.0)) -@test isequal(sqrt(MPCComplex(Inf,5.0)), MPCComplex(Inf,0.0)) -@test isequal(sqrt(MPCComplex(Inf,-0.0)), MPCComplex(Inf,-0.0)) -@test isequal(sqrt(MPCComplex(Inf,-5.0)), MPCComplex(Inf,-0.0)) - -@test isequal(sqrt(MPCComplex(-Inf,NaN)), MPCComplex(NaN,Inf)) -@test isequal(sqrt(MPCComplex(Inf,NaN)), MPCComplex(Inf,NaN)) - -@test isequal(sqrt(MPCComplex(NaN,0.0)), MPCComplex(NaN,NaN)) -@test isequal(sqrt(MPCComplex(NaN,0.0)), MPCComplex(NaN,NaN)) - - - -# log: -# log(conj(z)) = conj(log(z)) -@test isequal(log(MPCComplex(5.0,0.0)),MPCComplex(log(5.0),0.0)) -@test isequal(log(MPCComplex(5.0,-0.0)),MPCComplex(log(5.0),-0.0)) - -@test isequal(log(MPCComplex(0.0,1.0)),MPCComplex(0.0,pi/2)) -@test isequal(log(MPCComplex(0.0,-1.0)),MPCComplex(0.0,-pi/2)) - -# special values - -# raise divide-by-zero flag -@test isequal(log(MPCComplex(-0.0,0.0)), MPCComplex(-Inf,pi)) -@test isequal(log(MPCComplex(-0.0,-0.0)), MPCComplex(-Inf,-pi)) - -# raise divide-by-zero flag -@test isequal(log(MPCComplex(0.0,0.0)), MPCComplex(-Inf,0.0)) -@test isequal(log(MPCComplex(0.0,-0.0)), MPCComplex(-Inf,-0.0)) - -@test isequal(log(MPCComplex(0.0,Inf)), MPCComplex(Inf,pi/2)) -@test isequal(log(MPCComplex(0.0,-Inf)), MPCComplex(Inf,-pi/2)) - -@test isequal(log(MPCComplex(0.0,NaN)), MPCComplex(NaN,NaN)) - -@test isequal(log(MPCComplex(-Inf,5.0)), MPCComplex(Inf,pi)) -@test isequal(log(MPCComplex(-Inf,-5.0)), MPCComplex(Inf,-pi)) - -@test isequal(log(MPCComplex(Inf,5.0)), MPCComplex(Inf,0.0)) -@test isequal(log(MPCComplex(Inf,-5.0)), MPCComplex(Inf,-0.0)) - -@test isequal(log(MPCComplex(-Inf,Inf)), MPCComplex(Inf,3*pi/4)) -@test isequal(log(MPCComplex(-Inf,-Inf)), MPCComplex(Inf,-3*pi/4)) - -@test isequal(log(MPCComplex(Inf,Inf)), MPCComplex(Inf,pi/4)) -@test isequal(log(MPCComplex(Inf,-Inf)), MPCComplex(Inf,-pi/4)) - -@test isequal(log(MPCComplex(Inf,NaN)), MPCComplex(Inf,NaN)) -@test isequal(log(MPCComplex(-Inf,NaN)), MPCComplex(Inf,NaN)) - -@test isequal(log(MPCComplex(NaN,0.0)), MPCComplex(NaN,NaN)) - -@test isequal(log(MPCComplex(NaN,Inf)), MPCComplex(Inf,NaN)) -@test isequal(log(MPCComplex(NaN,-Inf)), MPCComplex(Inf,NaN)) - -@test isequal(log(MPCComplex(NaN,NaN)), MPCComplex(NaN,NaN)) - -# exp: -# exp(conj(z)) = conj(exp(z)) - -@test isequal(exp(MPCComplex(0.0,0.0)), MPCComplex(1.0,0.0)) -@test isequal(exp(MPCComplex(0.0,-0.0)), MPCComplex(1.0,-0.0)) -@test isequal(exp(MPCComplex(-0.0,0.0)), MPCComplex(1.0,0.0)) -@test isequal(exp(MPCComplex(-0.0,-0.0)), MPCComplex(1.0,-0.0)) - -# raise invalid flag -@test isequal(exp(MPCComplex(0.0,Inf)), MPCComplex(NaN,NaN)) -@test isequal(exp(MPCComplex(0.0,-Inf)), MPCComplex(NaN,NaN)) -@test isequal(exp(MPCComplex(5.0,Inf)), MPCComplex(NaN,NaN)) - -@test isequal(exp(MPCComplex(0.0,NaN)), MPCComplex(NaN,NaN)) - -@test isequal(exp(MPCComplex(Inf,0.0)), MPCComplex(Inf,0.0)) -@test isequal(exp(MPCComplex(Inf,-0.0)), MPCComplex(Inf,-0.0)) - -@test isequal(exp(MPCComplex(-Inf,0.0)), MPCComplex(0.0,0.0)) -@test isequal(exp(MPCComplex(-Inf,-0.0)), MPCComplex(0.0,-0.0)) -@test isequal(exp(MPCComplex(-Inf,5.0)), MPCComplex(cos(5.0)*0.0,sin(5.0)*0.0)) -@test isequal(exp(MPCComplex(-Inf,-5.0)), MPCComplex(cos(5.0)*0.0,sin(5.0)*-0.0)) - -@test isequal(exp(MPCComplex(Inf,5.0)), MPCComplex(cos(5.0)*Inf,sin(5.0)*Inf)) -@test isequal(exp(MPCComplex(Inf,-5.0)), MPCComplex(cos(5.0)*Inf,sin(5.0)*-Inf)) - -@test isequal(exp(MPCComplex(-Inf,Inf)), MPCComplex(-0.0,0.0)) -@test isequal(exp(MPCComplex(-Inf,-Inf)), MPCComplex(-0.0,-0.0)) - -# raise invalid flag -# TODO: The left side evaluates to MPCComplex(Inf, NaN) -#@test isequal(exp(MPCComplex(Inf,Inf)), MPCComplex(-Inf,NaN)) -#@test isequal(exp(MPCComplex(Inf,-Inf)), MPCComplex(-Inf,NaN)) - -@test isequal(exp(MPCComplex(-Inf,NaN)), MPCComplex(-0.0,0.0)) - -# TODO: The left side evaluates to MPCComplex(Inf, NaN) -#@test isequal(exp(MPCComplex(Inf,NaN)), MPCComplex(-Inf,NaN)) - -@test isequal(exp(MPCComplex(NaN,0.0)), MPCComplex(NaN,0.0)) -@test isequal(exp(MPCComplex(NaN,-0.0)), MPCComplex(NaN,-0.0)) - -@test isequal(exp(MPCComplex(NaN,5.0)), MPCComplex(NaN,NaN)) - -@test isequal(exp(MPCComplex(NaN,NaN)), MPCComplex(NaN,NaN)) - -# ^ (cpow) -# equivalent to exp(y*log(x)) -# except for 0^0? -# conj(x)^conj(y) = conj(x^y) -@test isequal(MPCComplex(0.0,0.0)^MPCComplex(0.0,0.0), MPCComplex(1.0,-0.0)) -@test isequal(MPCComplex(0.0,-0.0)^MPCComplex(0.0,0.0), MPCComplex(1.0,-0.0)) -@test isequal(MPCComplex(0.0,0.0)^MPCComplex(0.0,-0.0), MPCComplex(1.0,0.0)) -@test isequal(MPCComplex(0.0,-0.0)^MPCComplex(0.0,-0.0), MPCComplex(1.0,0.0)) -@test isequal(MPCComplex(-0.0,0.0)^MPCComplex(0.0,0.0), MPCComplex(1.0,-0.0)) -@test isequal(MPCComplex(-0.0,-0.0)^MPCComplex(0.0,0.0), MPCComplex(1.0,-0.0)) -@test isequal(MPCComplex(-0.0,0.0)^MPCComplex(0.0,-0.0), MPCComplex(1.0,0.0)) -@test isequal(MPCComplex(-0.0,-0.0)^MPCComplex(0.0,-0.0), MPCComplex(1.0,0.0)) -@test isequal(MPCComplex(0.0,0.0)^MPCComplex(-0.0,0.0), MPCComplex(1.0,-0.0)) -@test isequal(MPCComplex(0.0,-0.0)^MPCComplex(-0.0,0.0), MPCComplex(1.0,-0.0)) -@test isequal(MPCComplex(0.0,0.0)^MPCComplex(-0.0,-0.0), MPCComplex(1.0,0.0)) -@test isequal(MPCComplex(0.0,-0.0)^MPCComplex(-0.0,-0.0), MPCComplex(1.0,0.0)) -@test isequal(MPCComplex(-0.0,0.0)^MPCComplex(-0.0,0.0), MPCComplex(1.0,-0.0)) -@test isequal(MPCComplex(-0.0,-0.0)^MPCComplex(-0.0,0.0), MPCComplex(1.0,-0.0)) -@test isequal(MPCComplex(-0.0,0.0)^MPCComplex(-0.0,-0.0), MPCComplex(1.0,0.0)) -@test isequal(MPCComplex(-0.0,-0.0)^MPCComplex(-0.0,-0.0), MPCComplex(1.0,0.0)) - - - - -# sinh: has properties -# sinh(conj(z)) = conj(sinh(z)) -# sinh(-z) = -sinh(z) - -@test isequal(sinh(MPCComplex(0.0,0.0)),MPCComplex(0.0,0.0)) -@test isequal(sinh(MPCComplex(0.0,-0.0)),MPCComplex(0.0,-0.0)) -@test isequal(sinh(MPCComplex(-0.0,0.0)),MPCComplex(-0.0,0.0)) -@test isequal(sinh(MPCComplex(-0.0,-0.0)),MPCComplex(-0.0,-0.0)) - -# raise invalid flag -@test isequal(sinh(MPCComplex(0.0,Inf)), MPCComplex(0.0,NaN)) -@test isequal(sinh(MPCComplex(0.0,-Inf)), MPCComplex(0.0,NaN)) -@test isequal(sinh(MPCComplex(-0.0,Inf)), MPCComplex(-0.0,NaN)) -@test isequal(sinh(MPCComplex(-0.0,-Inf)), MPCComplex(-0.0,NaN)) - -@test isequal(sinh(MPCComplex(0.0,NaN)),MPCComplex(0.0,NaN)) -@test isequal(sinh(MPCComplex(-0.0,NaN)),MPCComplex(-0.0,NaN)) - -# raise invalid flag -@test isequal(sinh(MPCComplex(5.0,Inf)), MPCComplex(NaN,NaN)) - -@test isequal(sinh(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) - -@test isequal(sinh(MPCComplex(Inf,0.0)),MPCComplex(Inf,0.0)) -@test isequal(sinh(MPCComplex(Inf,-0.0)),MPCComplex(Inf,-0.0)) -@test isequal(sinh(MPCComplex(-Inf,0.0)),MPCComplex(-Inf,0.0)) -@test isequal(sinh(MPCComplex(-Inf,-0.0)),MPCComplex(-Inf,-0.0)) - -@test isequal(sinh(MPCComplex(Inf,5.0)),MPCComplex(cos(5.0)*Inf,sin(5.0)*Inf)) -@test isequal(sinh(MPCComplex(-Inf,5.0)),MPCComplex(cos(5.0)*-Inf,sin(5.0)*Inf)) - -# raise invalid flag -@test isequal(sinh(MPCComplex(Inf,Inf)), MPCComplex(Inf,NaN)) -@test isequal(sinh(MPCComplex(Inf,-Inf)), MPCComplex(Inf,NaN)) -@test isequal(sinh(MPCComplex(-Inf,Inf)), MPCComplex(-Inf,NaN)) -@test isequal(sinh(MPCComplex(-Inf,-Inf)), MPCComplex(-Inf,NaN)) - -@test isequal(sinh(MPCComplex(Inf,NaN)),MPCComplex(Inf,NaN)) -@test isequal(sinh(MPCComplex(-Inf,NaN)),MPCComplex(-Inf,NaN)) - -@test isequal(sinh(MPCComplex(NaN,0.0)),MPCComplex(NaN,0.0)) -@test isequal(sinh(MPCComplex(NaN,-0.0)),MPCComplex(NaN,-0.0)) - -@test isequal(sinh(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) - -@test isequal(sinh(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) - - - -# sin: defined in terms of sinh -# sin(z) = -i*sinh(i*z) -# i.e. if sinh(a+ib) = x+iy -# then sin(b-ia) = y-ix -# sin(conj(z)) = conj(sin(z)) -# sin(-z) = -sin(z) - - -@test isequal(sin(MPCComplex(0.0,-0.0)),MPCComplex(0.0,-0.0)) -@test isequal(sin(MPCComplex(-0.0,-0.0)),MPCComplex(-0.0,-0.0)) -@test isequal(sin(MPCComplex(0.0,0.0)),MPCComplex(0.0,0.0)) -@test isequal(sin(MPCComplex(-0.0,0.0)),MPCComplex(-0.0,0.0)) - -# raise invalid flag -@test isequal(sin(MPCComplex(Inf,0.0)), MPCComplex(NaN,0.0)) -@test isequal(sin(MPCComplex(-Inf,0.0)), MPCComplex(NaN,0.0)) -@test isequal(sin(MPCComplex(Inf,-0.0)), MPCComplex(NaN,-0.0)) -@test isequal(sin(MPCComplex(-Inf,-0.0)), MPCComplex(NaN,-0.0)) - -@test isequal(sin(MPCComplex(NaN,0.0)),MPCComplex(NaN,0.0)) -@test isequal(sin(MPCComplex(NaN,-0.0)),MPCComplex(NaN,-0.0)) - -# raise invalid flag -@test isequal(sin(MPCComplex(Inf,5.0)), MPCComplex(NaN,NaN)) - -@test isequal(sin(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) - -@test isequal(sin(MPCComplex(0.0,Inf)),MPCComplex(0.0,Inf)) -@test isequal(sin(MPCComplex(-0.0,Inf)),MPCComplex(-0.0,Inf)) -@test isequal(sin(MPCComplex(0.0,-Inf)),MPCComplex(0.0,-Inf)) -@test isequal(sin(MPCComplex(-0.0,-Inf)),MPCComplex(-0.0,-Inf)) - -@test isequal(sin(MPCComplex(5.0,Inf)),MPCComplex(sin(5.0)*Inf,cos(5.0)*Inf)) -@test isequal(sin(MPCComplex(5.0,-Inf)),MPCComplex(sin(5.0)*Inf,cos(5.0)*-Inf)) - -# raise invalid flag -@test isequal(sin(MPCComplex(Inf,Inf)), MPCComplex(Inf,NaN)) -@test isequal(sin(MPCComplex(Inf,-Inf)), MPCComplex(Inf,NaN)) -@test isequal(sin(MPCComplex(-Inf,Inf)), MPCComplex(-Inf,NaN)) -@test isequal(sin(MPCComplex(-Inf,-Inf)), MPCComplex(-Inf,NaN)) - -@test isequal(sin(MPCComplex(NaN,Inf)),MPCComplex(NaN,Inf)) -@test isequal(sin(MPCComplex(NaN,-Inf)),MPCComplex(NaN,-Inf)) - -@test isequal(sin(MPCComplex(0.0,NaN)),MPCComplex(0.0,NaN)) -@test isequal(sin(MPCComplex(-0.0,NaN)),MPCComplex(-0.0,NaN)) - -@test isequal(sin(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) - -@test isequal(sin(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) - - - - - - -# cosh: has properties -# cosh(conj(z)) = conj(cosh(z)) -# coshh(-z) = cosh(z) - -@test isequal(cosh(MPCComplex(0.0,0.0)),MPCComplex(1.0,0.0)) -@test isequal(cosh(MPCComplex(0.0,-0.0)),MPCComplex(1.0,-0.0)) -@test isequal(cosh(MPCComplex(-0.0,-0.0)),MPCComplex(1.0,0.0)) -@test isequal(cosh(MPCComplex(-0.0,0.0)),MPCComplex(1.0,-0.0)) - -# raise invalid flag -@test isequal(cosh(MPCComplex(0.0,Inf)), MPCComplex(NaN,0.0)) -@test isequal(cosh(MPCComplex(0.0,-Inf)), MPCComplex(NaN,-0.0)) - -@test isequal(cosh(MPCComplex(0.0,NaN)),MPCComplex(NaN,0.0)) -@test isequal(cosh(MPCComplex(-0.0,NaN)),MPCComplex(NaN,0.0)) - -# raise invalid flag -@test isequal(cosh(MPCComplex(5.0,Inf)), MPCComplex(NaN,NaN)) - -@test isequal(cosh(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) - -@test isequal(cosh(MPCComplex(Inf,0.0)),MPCComplex(Inf,0.0)) -@test isequal(cosh(MPCComplex(Inf,-0.0)),MPCComplex(Inf,-0.0)) -@test isequal(cosh(MPCComplex(-Inf,-0.0)),MPCComplex(Inf,0.0)) -@test isequal(cosh(MPCComplex(-Inf,0.0)),MPCComplex(Inf,-0.0)) - -@test isequal(cosh(MPCComplex(Inf,5.0)),MPCComplex(cos(5.0)*Inf,sin(5.0)*Inf)) -@test isequal(cosh(MPCComplex(Inf,-5.0)),MPCComplex(cos(5.0)*Inf,sin(5.0)*-Inf)) -@test isequal(cosh(MPCComplex(-Inf,-5.0)),MPCComplex(cos(5.0)*Inf,sin(5.0)*Inf)) -@test isequal(cosh(MPCComplex(-Inf,5.0)),MPCComplex(cos(5.0)*Inf,sin(5.0)*-Inf)) - -# raise invalid flag -@test isequal(cosh(MPCComplex(Inf,Inf)), MPCComplex(Inf,NaN)) -# TODO: The left side evaluates to MPCComplex(-Inf, NaN) -#@test isequal(cosh(MPCComplex(Inf,-Inf)), MPCComplex(Inf,NaN)) -@test isequal(cosh(MPCComplex(-Inf,-Inf)), MPCComplex(Inf,NaN)) -# TODO: The left side evaluates to MPCComplex(-Inf, NaN) -#@test isequal(cosh(MPCComplex(-Inf,Inf)), MPCComplex(Inf,NaN)) - -@test isequal(cosh(MPCComplex(Inf,NaN)),MPCComplex(Inf,NaN)) -@test isequal(cosh(MPCComplex(-Inf,NaN)),MPCComplex(Inf,NaN)) - -@test isequal(cosh(MPCComplex(NaN,0.0)),MPCComplex(NaN,0.0)) -@test isequal(cosh(MPCComplex(NaN,-0.0)),MPCComplex(NaN,-0.0)) - -@test isequal(cosh(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) -@test isequal(cosh(MPCComplex(NaN,-5.0)),MPCComplex(NaN,NaN)) - -@test isequal(cosh(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) - - -# cos -# cos(z) = cosh(iz) -# i.e cos(b-ia) = cosh(a+ib) -# and cos(b+ia) = cosh(a-ib) -# cos(conj(z)) = conj(cos(z)) -# cos(-z) = cos(z) - -@test isequal(cos(MPCComplex(0.0,0.0)),MPCComplex(1.0,-0.0)) -@test isequal(cos(MPCComplex(0.0,-0.0)),MPCComplex(1.0,0.0)) -@test isequal(cos(MPCComplex(-0.0,0.0)),MPCComplex(1.0,0.0)) -@test isequal(cos(MPCComplex(-0.0,-0.0)),MPCComplex(1.0,-0.0)) - -# raise invalid flag -@test isequal(cos(MPCComplex(Inf,0.0)), MPCComplex(NaN,-0.0)) -@test isequal(cos(MPCComplex(-Inf,0.0)), MPCComplex(NaN,0.0)) - -@test isequal(cos(MPCComplex(NaN,0.0)),MPCComplex(NaN,0.0)) -@test isequal(cos(MPCComplex(NaN,-0.0)),MPCComplex(NaN,0.0)) - -# raise invalid flag -@test isequal(cos(MPCComplex(Inf,5.0)), MPCComplex(NaN,NaN)) - -@test isequal(cos(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) - -@test isequal(cos(MPCComplex(0.0,-Inf)),MPCComplex(Inf,0.0)) -@test isequal(cos(MPCComplex(-0.0,-Inf)),MPCComplex(Inf,-0.0)) -@test isequal(cos(MPCComplex(-0.0,Inf)),MPCComplex(Inf,0.0)) -@test isequal(cos(MPCComplex(0.0,Inf)),MPCComplex(Inf,-0.0)) - -@test isequal(cos(MPCComplex(5.0,-Inf)),MPCComplex(cos(5.0)*Inf,sin(5.0)*Inf)) -@test isequal(cos(MPCComplex(-5.0,-Inf)),MPCComplex(cos(5.0)*Inf,sin(5.0)*-Inf)) -@test isequal(cos(MPCComplex(-5.0,Inf)),MPCComplex(cos(5.0)*Inf,sin(5.0)*Inf)) -@test isequal(cos(MPCComplex(5.0,Inf)),MPCComplex(cos(5.0)*Inf,sin(5.0)*-Inf)) - -# raise invalid flag -# TODO: The left side evaluates to MPCComplex(-Inf, NaN) -#@test isequal(cos(MPCComplex(Inf,Inf)), MPCComplex(Inf,NaN)) -@test isequal(cos(MPCComplex(Inf,-Inf)), MPCComplex(Inf,NaN)) -# TODO: The left side evaluates to MPCComplex(-Inf, NaN) -#@test isequal(cos(MPCComplex(-Inf,-Inf)), MPCComplex(Inf,NaN)) -@test isequal(cos(MPCComplex(-Inf,Inf)), MPCComplex(Inf,NaN)) - -@test isequal(cos(MPCComplex(NaN,Inf)),MPCComplex(Inf,NaN)) -@test isequal(cos(MPCComplex(NaN,-Inf)),MPCComplex(Inf,NaN)) - -@test isequal(cos(MPCComplex(0.0,NaN)),MPCComplex(NaN,0.0)) -@test isequal(cos(MPCComplex(-0.0,NaN)),MPCComplex(NaN,-0.0)) - -@test isequal(cos(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) -@test isequal(cos(MPCComplex(-5.0,NaN)),MPCComplex(NaN,NaN)) - -@test isequal(cos(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) - - - - -# tanh -# tanh(conj(z)) = conj(tanh(z)) -# tanh(-z) = -tanh(z) -@test isequal(tanh(MPCComplex(0.0,0.0)),MPCComplex(0.0,0.0)) -@test isequal(tanh(MPCComplex(0.0,-0.0)),MPCComplex(0.0,-0.0)) -@test isequal(tanh(MPCComplex(-0.0,0.0)),MPCComplex(-0.0,0.0)) -@test isequal(tanh(MPCComplex(-0.0,-0.0)),MPCComplex(-0.0,-0.0)) - -# raise invalid flag -@test isequal(tanh(MPCComplex(0.0,Inf)), MPCComplex(NaN,0.0)) -@test isequal(tanh(MPCComplex(0.0,-Inf)), MPCComplex(NaN,-0.0)) - -@test isequal(tanh(MPCComplex(0.0,NaN)),MPCComplex(NaN,NaN)) - -# raise invalid flag -@test isequal(tanh(MPCComplex(5.0,Inf)), MPCComplex(NaN,NaN)) - -@test isequal(tanh(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) - -@test isequal(tanh(MPCComplex(Inf,0.0)),MPCComplex(1.0,0.0)) -@test isequal(tanh(MPCComplex(Inf,-0.0)),MPCComplex(1.0,-0.0)) -@test isequal(tanh(MPCComplex(-Inf,0.0)),MPCComplex(-1.0,0.0)) -@test isequal(tanh(MPCComplex(-Inf,-0.0)),MPCComplex(-1.0,-0.0)) - -@test isequal(tanh(MPCComplex(Inf,5.0)),MPCComplex(1.0,sin(2*5.0)*0.0)) -@test isequal(tanh(MPCComplex(Inf,-5.0)),MPCComplex(1.0,sin(2*5.0)*-0.0)) -@test isequal(tanh(MPCComplex(-Inf,5.0)),MPCComplex(-1.0,sin(2*5.0)*0.0)) -@test isequal(tanh(MPCComplex(-Inf,-5.0)),MPCComplex(-1.0,sin(2*5.0)*-0.0)) - -@test isequal(tanh(MPCComplex(Inf,Inf)),MPCComplex(1.0,0.0)) -@test isequal(tanh(MPCComplex(Inf,-Inf)),MPCComplex(1.0,-0.0)) -@test isequal(tanh(MPCComplex(-Inf,Inf)),MPCComplex(-1.0,0.0)) -@test isequal(tanh(MPCComplex(-Inf,-Inf)),MPCComplex(-1.0,-0.0)) - -@test isequal(tanh(MPCComplex(Inf,NaN)),MPCComplex(1.0,0.0)) -@test isequal(tanh(MPCComplex(-Inf,NaN)),MPCComplex(-1.0,0.0)) - -@test isequal(tanh(MPCComplex(NaN,0.0)),MPCComplex(NaN,0.0)) -@test isequal(tanh(MPCComplex(NaN,-0.0)),MPCComplex(NaN,-0.0)) - -@test isequal(tanh(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) -@test isequal(tanh(MPCComplex(NaN,-5.0)),MPCComplex(NaN,NaN)) - -@test isequal(tanh(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) - -# tan -# tan(z) = -i tanh(iz) -@test isequal(tan(MPCComplex(Inf,5.0)), MPCComplex(NaN,NaN)) - -@test isequal(tan(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) - -@test isequal(tan(MPCComplex(0.0,Inf)),MPCComplex(0.0,1.0)) -@test isequal(tan(MPCComplex(-0.0,Inf)),MPCComplex(-0.0,1.0)) -@test isequal(tan(MPCComplex(0.0,-Inf)),MPCComplex(0.0,-1.0)) -@test isequal(tan(MPCComplex(-0.0,-Inf)),MPCComplex(-0.0,-1.0)) - -@test isequal(tan(MPCComplex(5.0,Inf)),MPCComplex(sin(2*5.0)*0.0,1.0)) -@test isequal(tan(MPCComplex(-5.0,Inf)),MPCComplex(sin(2*5.0)*-0.0,1.0)) -@test isequal(tan(MPCComplex(5.0,-Inf)),MPCComplex(sin(2*5.0)*0.0,-1.0)) -@test isequal(tan(MPCComplex(-5.0,-Inf)),MPCComplex(sin(2*5.0)*-0.0,-1.0)) - -@test isequal(tan(MPCComplex(Inf,Inf)),MPCComplex(0.0,1.0)) -@test isequal(tan(MPCComplex(-Inf,Inf)),MPCComplex(-0.0,1.0)) -@test isequal(tan(MPCComplex(Inf,-Inf)),MPCComplex(0.0,-1.0)) -@test isequal(tan(MPCComplex(-Inf,-Inf)),MPCComplex(-0.0,-1.0)) - -@test isequal(tan(MPCComplex(NaN,Inf)),MPCComplex(0.0,1.0)) -@test isequal(tan(MPCComplex(NaN,-Inf)),MPCComplex(0.0,-1.0)) - -@test isequal(tan(MPCComplex(0.0,NaN)),MPCComplex(0.0,NaN)) -@test isequal(tan(MPCComplex(-0.0,NaN)),MPCComplex(-0.0,NaN)) - -@test isequal(tan(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) -@test isequal(tan(MPCComplex(-5.0,NaN)),MPCComplex(NaN,NaN)) - -@test isequal(tan(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) - - - - -# acosh -# acosh(conj(z)) = conj(acosh(z)) -@test isequal(acosh(MPCComplex(0.0,0.0)),MPCComplex(0.0,pi/2)) -@test isequal(acosh(MPCComplex(0.0,-0.0)),MPCComplex(0.0,-pi/2)) -@test isequal(acosh(MPCComplex(-0.0,0.0)),MPCComplex(0.0,pi/2)) -@test isequal(acosh(MPCComplex(-0.0,-0.0)),MPCComplex(0.0,-pi/2)) - -@test isequal(acosh(MPCComplex(0.0,Inf)),MPCComplex(Inf,pi/2)) -@test isequal(acosh(MPCComplex(0.0,-Inf)),MPCComplex(Inf,-pi/2)) -@test isequal(acosh(MPCComplex(5.0,Inf)),MPCComplex(Inf,pi/2)) -@test isequal(acosh(MPCComplex(5.0,-Inf)),MPCComplex(Inf,-pi/2)) - -@test isequal(acosh(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) - -@test isequal(acosh(MPCComplex(-Inf,0.0)),MPCComplex(Inf,pi)) -@test isequal(acosh(MPCComplex(-Inf,-0.0)),MPCComplex(Inf,-pi)) -@test isequal(acosh(MPCComplex(-Inf,5.0)),MPCComplex(Inf,pi)) -@test isequal(acosh(MPCComplex(-Inf,-5.0)),MPCComplex(Inf,-pi)) - -@test isequal(acosh(MPCComplex(Inf,0.0)),MPCComplex(Inf,0.0)) -@test isequal(acosh(MPCComplex(Inf,-0.0)),MPCComplex(Inf,-0.0)) -@test isequal(acosh(MPCComplex(Inf,5.0)),MPCComplex(Inf,0.0)) -@test isequal(acosh(MPCComplex(Inf,-5.0)),MPCComplex(Inf,-0.0)) - -@test isequal(acosh(MPCComplex(-Inf,Inf)),MPCComplex(Inf,3*pi/4)) -@test isequal(acosh(MPCComplex(-Inf,-Inf)),MPCComplex(Inf,-3*pi/4)) - -@test isequal(acosh(MPCComplex(Inf,Inf)),MPCComplex(Inf,pi/4)) -@test isequal(acosh(MPCComplex(Inf,-Inf)),MPCComplex(Inf,-pi/4)) - -@test isequal(acosh(MPCComplex(Inf,NaN)),MPCComplex(Inf,NaN)) -@test isequal(acosh(MPCComplex(-Inf,NaN)),MPCComplex(Inf,NaN)) - -@test isequal(acosh(MPCComplex(NaN,Inf)),MPCComplex(Inf,NaN)) -@test isequal(acosh(MPCComplex(NaN,-Inf)),MPCComplex(Inf,NaN)) - -@test isequal(acosh(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) - - -# acos -# acos(conj(z)) = conj(acos(z)) -@test isequal(acos(MPCComplex(0.0,0.0)),MPCComplex(pi/2,-0.0)) -@test isequal(acos(MPCComplex(0.0,-0.0)),MPCComplex(pi/2,0.0)) -@test isequal(acos(MPCComplex(-0.0,0.0)),MPCComplex(pi/2,-0.0)) -@test isequal(acos(MPCComplex(-0.0,-0.0)),MPCComplex(pi/2,0.0)) - -@test isequal(acos(MPCComplex(0.0,NaN)),MPCComplex(pi/2,NaN)) -@test isequal(acos(MPCComplex(-0.0,NaN)),MPCComplex(pi/2,NaN)) - -@test isequal(acos(MPCComplex(0.0,Inf)),MPCComplex(pi/2,-Inf)) -@test isequal(acos(MPCComplex(0.0,-Inf)),MPCComplex(pi/2,Inf)) -@test isequal(acos(MPCComplex(5.0,Inf)),MPCComplex(pi/2,-Inf)) -@test isequal(acos(MPCComplex(5.0,-Inf)),MPCComplex(pi/2,Inf)) - -@test isequal(acos(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) - -@test isequal(acos(MPCComplex(-Inf,0.0)),MPCComplex(pi,-Inf)) -@test isequal(acos(MPCComplex(-Inf,-0.0)),MPCComplex(pi,Inf)) -@test isequal(acos(MPCComplex(-Inf,5.0)),MPCComplex(pi,-Inf)) -@test isequal(acos(MPCComplex(-Inf,-5.0)),MPCComplex(pi,Inf)) - -@test isequal(acos(MPCComplex(Inf,0.0)),MPCComplex(0.0,-Inf)) -@test isequal(acos(MPCComplex(Inf,-0.0)),MPCComplex(0.0,Inf)) -@test isequal(acos(MPCComplex(Inf,5.0)),MPCComplex(0.0,-Inf)) -@test isequal(acos(MPCComplex(Inf,-5.0)),MPCComplex(0.0,Inf)) - -@test isequal(acos(MPCComplex(-Inf,Inf)),MPCComplex(3*pi/4,-Inf)) -@test isequal(acos(MPCComplex(-Inf,-Inf)),MPCComplex(3*pi/4,Inf)) - -@test isequal(acos(MPCComplex(Inf,Inf)),MPCComplex(pi/4,-Inf)) -@test isequal(acos(MPCComplex(Inf,-Inf)),MPCComplex(pi/4,Inf)) - -# TODO: The left side evaluates to MPCComplex(NaN, -Inf) -#@test isequal(acos(MPCComplex(Inf,NaN)),MPCComplex(NaN,Inf)) -#@test isequal(acos(MPCComplex(-Inf,NaN)),MPCComplex(NaN,Inf)) - -@test isequal(acos(MPCComplex(NaN,0.0)),MPCComplex(NaN,NaN)) -@test isequal(acos(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) - -@test isequal(acos(MPCComplex(NaN,Inf)),MPCComplex(NaN,-Inf)) -@test isequal(acos(MPCComplex(NaN,-Inf)),MPCComplex(NaN,Inf)) - -@test isequal(acos(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) - - - -# asinh -# asinh(conj(z)) = conj(asinh(z)) -# asinh(-z) = -asinh(z) -@test isequal(asinh(MPCComplex(0.0,0.0)),MPCComplex(0.0,0.0)) -@test isequal(asinh(MPCComplex(0.0,-0.0)),MPCComplex(0.0,-0.0)) -@test isequal(asinh(MPCComplex(-0.0,0.0)),MPCComplex(-0.0,0.0)) -@test isequal(asinh(MPCComplex(-0.0,-0.0)),MPCComplex(-0.0,-0.0)) - -@test isequal(asinh(MPCComplex(0.0,Inf)),MPCComplex(Inf,pi/2)) -@test isequal(asinh(MPCComplex(0.0,-Inf)),MPCComplex(Inf,-pi/2)) -@test isequal(asinh(MPCComplex(-0.0,Inf)),MPCComplex(-Inf,pi/2)) -@test isequal(asinh(MPCComplex(-0.0,-Inf)),MPCComplex(-Inf,-pi/2)) - -@test isequal(asinh(MPCComplex(5.0,Inf)),MPCComplex(Inf,pi/2)) -@test isequal(asinh(MPCComplex(5.0,-Inf)),MPCComplex(Inf,-pi/2)) -@test isequal(asinh(MPCComplex(-5.0,Inf)),MPCComplex(-Inf,pi/2)) -@test isequal(asinh(MPCComplex(-5.0,-Inf)),MPCComplex(-Inf,-pi/2)) - -@test isequal(asinh(MPCComplex(0.0,NaN)),MPCComplex(NaN,NaN)) -@test isequal(asinh(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) - -@test isequal(asinh(MPCComplex(Inf,Inf)),MPCComplex(Inf,pi/4)) -@test isequal(asinh(MPCComplex(Inf,-Inf)),MPCComplex(Inf,-pi/4)) -@test isequal(asinh(MPCComplex(-Inf,Inf)),MPCComplex(-Inf,pi/4)) -@test isequal(asinh(MPCComplex(-Inf,-Inf)),MPCComplex(-Inf,-pi/4)) - -@test isequal(asinh(MPCComplex(Inf,NaN)),MPCComplex(Inf,NaN)) -@test isequal(asinh(MPCComplex(-Inf,NaN)),MPCComplex(-Inf,NaN)) - -@test isequal(asinh(MPCComplex(NaN,0.0)),MPCComplex(NaN,0.0)) -@test isequal(asinh(MPCComplex(NaN,-0.0)),MPCComplex(NaN,-0.0)) - -@test isequal(asinh(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) - -@test isequal(asinh(MPCComplex(NaN,Inf)),MPCComplex(Inf,NaN)) -@test isequal(asinh(MPCComplex(NaN,-Inf)),MPCComplex(Inf,NaN)) - -@test isequal(asinh(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) - - -# asin -# asin(z) = -i*asinh(iz) -@test isequal(asin(MPCComplex(0.0,0.0)),MPCComplex(0.0,0.0)) -@test isequal(asin(MPCComplex(0.0,-0.0)),MPCComplex(0.0,-0.0)) -@test isequal(asin(MPCComplex(-0.0,0.0)),MPCComplex(-0.0,0.0)) -@test isequal(asin(MPCComplex(-0.0,-0.0)),MPCComplex(-0.0,-0.0)) - -@test isequal(asin(MPCComplex(Inf,0.0)),MPCComplex(pi/2,Inf)) -@test isequal(asin(MPCComplex(-Inf,0.0)),MPCComplex(-pi/2,Inf)) -@test isequal(asin(MPCComplex(Inf,-0.0)),MPCComplex(pi/2,-Inf)) -@test isequal(asin(MPCComplex(-Inf,-0.0)),MPCComplex(-pi/2,-Inf)) - -@test isequal(asin(MPCComplex(Inf,5.0)),MPCComplex(pi/2,Inf)) -@test isequal(asin(MPCComplex(-Inf,5.0)),MPCComplex(-pi/2,Inf)) -@test isequal(asin(MPCComplex(Inf,-5.0)),MPCComplex(pi/2,-Inf)) -@test isequal(asin(MPCComplex(-Inf,-5.0)),MPCComplex(-pi/2,-Inf)) - -@test isequal(asin(MPCComplex(NaN,0.0)),MPCComplex(NaN,NaN)) -@test isequal(asin(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) - -@test isequal(asin(MPCComplex(Inf,Inf)),MPCComplex(pi/4,Inf)) -@test isequal(asin(MPCComplex(Inf,-Inf)),MPCComplex(pi/4,-Inf)) -@test isequal(asin(MPCComplex(-Inf,Inf)),MPCComplex(-pi/4,Inf)) -@test isequal(asin(MPCComplex(-Inf,-Inf)),MPCComplex(-pi/4,-Inf)) - -@test isequal(asin(MPCComplex(NaN,Inf)),MPCComplex(NaN,Inf)) -@test isequal(asin(MPCComplex(NaN,-Inf)),MPCComplex(NaN,-Inf)) - -@test isequal(asin(MPCComplex(0.0,NaN)),MPCComplex(0.0,NaN)) -@test isequal(asin(MPCComplex(-0.0,NaN)),MPCComplex(-0.0,NaN)) - -@test isequal(asin(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) - -@test isequal(asin(MPCComplex(Inf,NaN)),MPCComplex(NaN,Inf)) -@test isequal(asin(MPCComplex(-Inf,NaN)),MPCComplex(NaN,Inf)) - -@test isequal(asin(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) - - - -# atanh -# atanh(conj(z)) = conj(atanh(z)) -# atang(-z) = -atanh(z) - -@test isequal(atanh(MPCComplex(0.0,0.0)),MPCComplex(0.0,0.0)) -@test isequal(atanh(MPCComplex(0.0,-0.0)),MPCComplex(0.0,-0.0)) -@test isequal(atanh(MPCComplex(-0.0,0.0)),MPCComplex(-0.0,0.0)) -@test isequal(atanh(MPCComplex(-0.0,-0.0)),MPCComplex(-0.0,-0.0)) - -@test isequal(atanh(MPCComplex(0.0,NaN)),MPCComplex(0.0,NaN)) -@test isequal(atanh(MPCComplex(-0.0,NaN)),MPCComplex(-0.0,NaN)) - -# raise divide-by-zero flag -@test isequal(atanh(MPCComplex(1.0,0.0)),MPCComplex(Inf,0.0)) - -@test isequal(atanh(MPCComplex(0.0,Inf)),MPCComplex(0.0,pi/2)) -@test isequal(atanh(MPCComplex(0.0,-Inf)),MPCComplex(0.0,-pi/2)) -@test isequal(atanh(MPCComplex(-0.0,Inf)),MPCComplex(-0.0,pi/2)) -@test isequal(atanh(MPCComplex(-0.0,-Inf)),MPCComplex(-0.0,-pi/2)) - -@test isequal(atanh(MPCComplex(5.0,Inf)),MPCComplex(0.0,pi/2)) -@test isequal(atanh(MPCComplex(5.0,-Inf)),MPCComplex(0.0,-pi/2)) -@test isequal(atanh(MPCComplex(-5.0,Inf)),MPCComplex(-0.0,pi/2)) -@test isequal(atanh(MPCComplex(-5.0,-Inf)),MPCComplex(-0.0,-pi/2)) - -@test isequal(atanh(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) -@test isequal(atanh(MPCComplex(-5.0,NaN)),MPCComplex(NaN,NaN)) - -@test isequal(atanh(MPCComplex(Inf,0.0)),MPCComplex(0.0,pi/2)) -@test isequal(atanh(MPCComplex(Inf,-0.0)),MPCComplex(0.0,-pi/2)) -@test isequal(atanh(MPCComplex(-Inf,0.0)),MPCComplex(-0.0,pi/2)) -@test isequal(atanh(MPCComplex(-Inf,-0.0)),MPCComplex(-0.0,-pi/2)) - -@test isequal(atanh(MPCComplex(Inf,5.0)),MPCComplex(0.0,pi/2)) -@test isequal(atanh(MPCComplex(Inf,-5.0)),MPCComplex(0.0,-pi/2)) -@test isequal(atanh(MPCComplex(-Inf,5.0)),MPCComplex(-0.0,pi/2)) -@test isequal(atanh(MPCComplex(-Inf,-5.0)),MPCComplex(-0.0,-pi/2)) - -@test isequal(atanh(MPCComplex(Inf,Inf)),MPCComplex(0.0,pi/2)) -@test isequal(atanh(MPCComplex(Inf,-Inf)),MPCComplex(0.0,-pi/2)) -@test isequal(atanh(MPCComplex(-Inf,Inf)),MPCComplex(-0.0,pi/2)) -@test isequal(atanh(MPCComplex(-Inf,-Inf)),MPCComplex(-0.0,-pi/2)) - -@test isequal(atanh(MPCComplex(Inf,NaN)),MPCComplex(0.0,NaN)) -@test isequal(atanh(MPCComplex(-Inf,NaN)),MPCComplex(-0.0,NaN)) - -@test isequal(atanh(MPCComplex(NaN,0.0)),MPCComplex(NaN,NaN)) -@test isequal(atanh(MPCComplex(NaN,-0.0)),MPCComplex(NaN,NaN)) -@test isequal(atanh(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) -@test isequal(atanh(MPCComplex(NaN,-5.0)),MPCComplex(NaN,NaN)) - -@test isequal(atanh(MPCComplex(NaN,Inf)),MPCComplex(0.0,pi/2)) -@test isequal(atanh(MPCComplex(NaN,-Inf)),MPCComplex(0.0,-pi/2)) - -@test isequal(atanh(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) - - -# atan -# atan(z) = -i*tanh(iz) - -@test isequal(atan(MPCComplex(0.0,0.0)),MPCComplex(0.0,0.0)) -@test isequal(atan(MPCComplex(0.0,-0.0)),MPCComplex(0.0,-0.0)) -@test isequal(atan(MPCComplex(-0.0,0.0)),MPCComplex(-0.0,0.0)) -@test isequal(atan(MPCComplex(-0.0,-0.0)),MPCComplex(-0.0,-0.0)) - -@test isequal(atan(MPCComplex(NaN,0.0)),MPCComplex(NaN,0.0)) -@test isequal(atan(MPCComplex(NaN,-0.0)),MPCComplex(NaN,-0.0)) - -# raise divide-by-zero flag -@test isequal(atan(MPCComplex(0.0,1.0)),MPCComplex(0.0,Inf)) - -@test isequal(atan(MPCComplex(Inf,0.0)),MPCComplex(pi/2,0.0)) -@test isequal(atan(MPCComplex(-Inf,0.0)),MPCComplex(-pi/2,0.0)) -@test isequal(atan(MPCComplex(Inf,-0.0)),MPCComplex(pi/2,-0.0)) -@test isequal(atan(MPCComplex(-Inf,-0.0)),MPCComplex(-pi/2,-0.0)) - -@test isequal(atan(MPCComplex(Inf,5.0)),MPCComplex(pi/2,0.0)) -@test isequal(atan(MPCComplex(-Inf,5.0)),MPCComplex(-pi/2,0.0)) -@test isequal(atan(MPCComplex(Inf,-5.0)),MPCComplex(pi/2,-0.0)) -@test isequal(atan(MPCComplex(-Inf,-5.0)),MPCComplex(-pi/2,-0.0)) - -@test isequal(atan(MPCComplex(NaN,5.0)),MPCComplex(NaN,NaN)) -@test isequal(atan(MPCComplex(NaN,-5.0)),MPCComplex(NaN,NaN)) - -@test isequal(atan(MPCComplex(0.0,Inf)),MPCComplex(pi/2,0.0)) -@test isequal(atan(MPCComplex(-0.0,Inf)),MPCComplex(-pi/2,0.0)) -@test isequal(atan(MPCComplex(0.0,-Inf)),MPCComplex(pi/2,-0.0)) -@test isequal(atan(MPCComplex(-0.0,-Inf)),MPCComplex(-pi/2,-0.0)) - -@test isequal(atan(MPCComplex(5.0,Inf)),MPCComplex(pi/2,0.0)) -@test isequal(atan(MPCComplex(-5.0,Inf)),MPCComplex(-pi/2,0.0)) -@test isequal(atan(MPCComplex(5.0,-Inf)),MPCComplex(pi/2,-0.0)) -@test isequal(atan(MPCComplex(-5.0,-Inf)),MPCComplex(-pi/2,-0.0)) - -@test isequal(atan(MPCComplex(Inf,Inf)),MPCComplex(pi/2,0.0)) -@test isequal(atan(MPCComplex(Inf,-Inf)),MPCComplex(pi/2,-0.0)) -@test isequal(atan(MPCComplex(-Inf,Inf)),MPCComplex(-pi/2,0.0)) -@test isequal(atan(MPCComplex(-Inf,-Inf)),MPCComplex(-pi/2,-0.0)) - -@test isequal(atan(MPCComplex(NaN,Inf)),MPCComplex(NaN,0.0)) -@test isequal(atan(MPCComplex(NaN,-Inf)),MPCComplex(NaN,-0.0)) - -@test isequal(atan(MPCComplex(0.0,NaN)),MPCComplex(NaN,NaN)) -@test isequal(atan(MPCComplex(-0.0,NaN)),MPCComplex(NaN,NaN)) -@test isequal(atan(MPCComplex(5.0,NaN)),MPCComplex(NaN,NaN)) -@test isequal(atan(MPCComplex(-5.0,NaN)),MPCComplex(NaN,NaN)) - -@test isequal(atan(MPCComplex(Inf,NaN)),MPCComplex(pi/2,0.0)) -@test isequal(atan(MPCComplex(-Inf,NaN)),MPCComplex(-pi/2,0.0)) - -@test isequal(atan(MPCComplex(NaN,NaN)),MPCComplex(NaN,NaN)) - -end # end precision change diff --git a/test/runtests.jl b/test/runtests.jl index ec86b2b63fffe..f180696d7afda 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,7 +4,7 @@ testnames = ["core", "keywordargs", "numbers", "strings", "unicode", "random", "math", "functional", "bigint", "sorting", "statistics", "spawn", "parallel", "priorityqueue", "arpack", "file", "perf", "suitesparse", "version", - "pollfd", "mpfr", "mpc"] + "pollfd", "mpfr"] # Disabled: "complex" From be7b6c946656fc515754da6129d429fa588ef367 Mon Sep 17 00:00:00 2001 From: Alessandro Andrioni Date: Fri, 3 May 2013 05:27:53 -0300 Subject: [PATCH 31/31] Remove MPC version --- deps/Versions.make | 1 - 1 file changed, 1 deletion(-) diff --git a/deps/Versions.make b/deps/Versions.make index 06a464c53bd51..0480610a58c94 100644 --- a/deps/Versions.make +++ b/deps/Versions.make @@ -12,7 +12,6 @@ SUITESPARSE_VER = 4.2.0 UNWIND_VER = 1.1 GMP_VER=5.1.1 MPFR_VER=3.1.2 -MPC_VER = 1.0.1 ZLIB_VER = 1.2.7 PATCHELF_VER = 0.6 GIT_VER = 1.8.2.1