Skip to content

Commit

Permalink
mpfr works with Apple. Set mpreal precision with GEOGRAPHICLIB_DIGITS.
Browse files Browse the repository at this point in the history
Add -p prec to all the *Proj utilities.
  • Loading branch information
Charles Karney committed Jul 19, 2014
1 parent a414384 commit f3971a0
Show file tree
Hide file tree
Showing 18 changed files with 221 additions and 127 deletions.
176 changes: 97 additions & 79 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,56 @@ set (GEOGRAPHICLIB_HAVE_LONG_DOUBLE ${HAVE_LONG_DOUBLE})
include (TestBigEndian)
test_big_endian (GEOGRAPHICLIB_WORDS_BIGENDIAN)

# Make the compiler more picky.
if (MSVC)
string (REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
else ()
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
# check for C++11 support. If available, the C++11 static_assert is
# used. This flag is *not* propagated to clients that use
# GeographicLib. However, this is of no consequence. When the client
# code is being compiled (and the GeographicLib headers being
# included), a work-alike substitution is used.
include (CheckCXXCompilerFlag)
set (CXX11_FLAG "-std=c++11")
check_cxx_compiler_flag (${CXX11_FLAG} CXX11TEST1)
if (NOT CXX11TEST1)
set (CXX11_FLAG "-std=c++0x")
check_cxx_compiler_flag (${CXX11_FLAG} CXX11TEST2)
if (NOT CXX11TEST2)
unset (CXX11_FLAG)
endif ()
endif ()
if (CXX11_FLAG)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX11_FLAG}")
endif ()
endif ()

# Check whether the C++11 math function: std::expm1, std::atanh,
# etc. are available. This flag is *not* propagated to clients that use
# GeographicLib. However, this is of no consequence. When the client
# code is being compiled (and the GeographicLib headers being included),
# work-alike substitutions are used.
include (CheckCXXSourceCompiles)
set (CMAKE_REQUIRED_FLAGS "${CMAKE_CXX_FLAGS}")
check_cxx_source_compiles (
"#include <cmath>
int main() {
return int(std::hypot(3.0, 4.0) + std::expm1(0.5) + std::log1p(2.0) +
std::asinh(10.0) + std::atanh(0.8) + std::cbrt(8.0)) +
std::isfinite(4.0) + std::isnan(0.0);
}\n" CXX11_MATH)
if (CXX11_MATH)
add_definitions (-DGEOGRAPHICLIB_CXX11_MATH=1)
else ()
add_definitions (-DGEOGRAPHICLIB_CXX11_MATH=0)
endif ()

# Set the include directories. Look in ${PROJECT_BINARY_DIR}/include
# first because that's where Config.h will be
include_directories ("${PROJECT_BINARY_DIR}/include" include)

if (GEOGRAPHICLIB_PRECISION EQUAL 1)
message (WARNING "Compiling with floats which results in poor accuracy")
elseif (GEOGRAPHICLIB_PRECISION EQUAL 2)
Expand All @@ -241,7 +291,7 @@ elseif (GEOGRAPHICLIB_PRECISION EQUAL 3)
set (GEOGRAPHICLIB_PRECISION 2)
endif ()
elseif (GEOGRAPHICLIB_PRECISION EQUAL 4)
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU)
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU AND CXX11_MATH)
# quad precision numbers appeared in Boost 1.54.
find_package (Boost 1.54)
if (Boost_FOUND)
Expand All @@ -261,29 +311,55 @@ elseif (GEOGRAPHICLIB_PRECISION EQUAL 4)
set (GEOGRAPHICLIB_PRECISION 2)
endif ()
elseif (GEOGRAPHICLIB_PRECISION EQUAL 5)
if (WIN32)
if (MSCV AND NOT MSVC_VERSION LESS 1800)
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
set (_ARCH x64)
else ()
set (_ARCH Win32)
if (CXX11_MATH)
# Install MPFR C++ version 3.5.9 or later from
# http://www.holoborodko.com/pavel/mpfr and install mpreal.h in the
# include directory. NOTE: MPFR C++ is covered by the GPL; be sure
# to abide by the terms of this license.
#
# For Linux, use system versions of mpfr and gmp. For Apple, use
# brew install mpfr. For Windows, download
# MPFR-MPIR-x86-x64-MSVC2010.zip from the MPFR C++ site and unpack
# in the top-level directory. NOTE: mpfr, gmp, and mpir are covered
# by the LGPL; be sure to abide by the terms of this license.
if (WIN32)
if (MSCV AND NOT MSVC_VERSION LESS 1800)
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
set (_ARCH x64)
else ()
set (_ARCH Win32)
endif ()
include_directories (mpfr_mpir_x86_x64_msvc2010/mpfr
mpfr_mpir_x86_x64_msvc2010/mpir/dll/${_ARCH}/Release)
# These are C libraries so it's OK to use release versions for
# debug builds. Also these work for later versions of Visual
# Studio (specifically version 12).
link_directories (mpfr_mpir_x86_x64_msvc2010/mpfr/dll/${_ARCH}/Release
mpfr_mpir_x86_x64_msvc2010/mpir/dll/${_ARCH}/Release)
set (MPFR_LIBRARIES mpfr mpir)
# Suppress the myriad of "conditional expression is constant"
# warnings
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4127")
endif ()
include_directories (mpfr_mpir_x86_x64_msvc2010/mpfr
mpfr_mpir_x86_x64_msvc2010/mpir/dll/${_ARCH}/Release)
# These are C libraries so it's OK to use release versions for debug
# builds. Also these will presumably work for later versions of
# Visual Studio.
link_directories (mpfr_mpir_x86_x64_msvc2010/mpfr/dll/${_ARCH}/Release
mpfr_mpir_x86_x64_msvc2010/mpir/dll/${_ARCH}/Release)
set (MPFR_LIBRARIES mpfr mpir)
# Suppress the myriad of "conditional expression is constant" warnings
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4127")
else ()
message (WARNING "Cannot support mpfr, switching to double")
set (GEOGRAPHICLIB_PRECISION 2)
if (APPLE)
include_directories (/usr/local/include)
link_directories (/usr/local/lib)
endif ()
set (MPFR_LIBRARIES mpfr gmp)
endif ()
else ()
set (MPFR_LIBRARIES mpfr gmp)
endif ()
if (NOT MPFR_LIBRARIES)
message (WARNING "Cannot support mpfr, switching to double")
set (GEOGRAPHICLIB_PRECISION 2)
endif ()
endif ()

if (APPLE AND GEOGRAPHICLIB_PRECISION EQUAL 2)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "i.86" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "amd64" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "x86")
set (CMAKE_OSX_ARCHITECTURES "i386 -arch x86_64")
endif ()
endif ()

Expand Down Expand Up @@ -359,60 +435,6 @@ if (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
set (CMAKE_BUILD_TYPE Release)
endif ()

# Make the compiler more picky.
if (MSVC)
string (REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
else ()
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
# check for C++11 support. If available, the C++11 static_assert is
# used. This flag is *not* propagated to clients that use
# GeographicLib. However, this is of no consequence. When the client
# code is being compiled (and the GeographicLib headers being
# included), a work-alike substitution is used.
include (CheckCXXCompilerFlag)
set (CXX11_FLAG "-std=c++11")
check_cxx_compiler_flag (${CXX11_FLAG} CXX11TEST1)
if (NOT CXX11TEST1)
set (CXX11_FLAG "-std=c++0x")
check_cxx_compiler_flag (${CXX11_FLAG} CXX11TEST2)
if (NOT CXX11TEST2)
unset (CXX11_FLAG)
endif ()
endif ()
if (CXX11_FLAG)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX11_FLAG}")
endif ()
endif ()

# Check whether the C++11 math function: std::expm1, std::atanh,
# etc. are available. This flag is *not* propagated to clients that use
# GeographicLib. However, this is of no consequence. When the client
# code is being compiled (and the GeographicLib headers being included),
# work-alike substitutions are used.
include (CheckCXXSourceCompiles)
set (CMAKE_REQUIRED_FLAGS "${CMAKE_CXX_FLAGS}")
check_cxx_source_compiles (
"#include <cmath>
int main() {
return int(std::hypot(3.0, 4.0) + std::expm1(0.5) + std::log1p(2.0) +
std::asinh(10.0) + std::atanh(0.8) + std::cbrt(8.0)) +
std::isfinite(4.0) + std::isnan(0.0);
}\n" CXX11_MATH)
if (CXX11_MATH)
add_definitions (-DGEOGRAPHICLIB_CXX11_MATH=1)
else ()
add_definitions (-DGEOGRAPHICLIB_CXX11_MATH=0)
endif ()

if (APPLE)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "i.86" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "amd64" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "x86")
set (CMAKE_OSX_ARCHITECTURES "i386 -arch x86_64")
endif ()
endif ()

# The list of tools (to be installed into, e.g., /usr/local/bin)
set (TOOLS CartConvert ConicProj GeodesicProj GeoConvert GeodSolve
GeoidEval Gravity MagneticField Planimeter TransverseMercatorProj)
Expand All @@ -422,10 +444,6 @@ set (SCRIPTS

set_property (GLOBAL PROPERTY USE_FOLDERS ON)

# Set the include directories. Look in ${PROJECT_BINARY_DIR}/include
# first because that's where Config.h will be
include_directories ("${PROJECT_BINARY_DIR}/include" include)

# The list of subdirectories to process
add_subdirectory (src)
add_subdirectory (include/GeographicLib)
Expand Down
9 changes: 4 additions & 5 deletions doc/GeographicLib.dox
Original file line number Diff line number Diff line change
Expand Up @@ -4827,18 +4827,17 @@ of the git repository for GeographicLib.
- Support quad precision.
- Support mpreal
- Add PolygonAreaT and PolygonAreaExact
- Add -E and -p options to Planimeter
- Add -Q option to Planimeter
- Add -p option to TransverseMercatorProj
- Add -E and -Q options to Planimeter
- Add -p option to Planimeter, ConicProj, GeodesicProj, and
TransverseMercatorProj.
- Retire Windows XP common data path.
- Simplify cross-platform support for C++11 mathematical functions.
- In NormalGravity, use Newton's method to determine f from J2.
- Add NormalGravity::J2ToFlattening and NormalGravity::FlatteningToJ2.
- In NormalGravity constructor allow omega = 0 (i.e., treat spherical case).
- Change way area coefficients are given in GeodesicExact to improve
compile times.
- STILL TO DO: add GravityModel for grs80.
- STILL TO DO: add -p prec for other utilities (where applicable)
- Add GravityModel for grs80.

- <a href="http://geographiclib.sf.net/1.36">Version 1.36</a>
(released 2014-05-13)
Expand Down
9 changes: 4 additions & 5 deletions include/GeographicLib/Math.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,16 +155,15 @@ namespace GeographicLib {
/**
* Set the binary precision of a real number.
*
* @param[in] prec the number of bits of precision. The default is 256 (or
* about 77 decimal digits).
* @param[in] digits the number of bits of precision.
*
* This only has an effect when GEOGRAPHICLIB_PRECISION == 5.
**********************************************************************/
static inline void set_digits(int prec = 256) {
static inline void set_digits(int digits) {
#if GEOGRAPHICLIB_PRECISION != 5
(void)prec;
(void)digits;
#else
mpfr::mpreal::set_default_prec(prec >= 2 ? prec : 2);
mpfr::mpreal::set_default_prec(digits >= 2 ? digits : 2);
#endif
}

Expand Down
12 changes: 12 additions & 0 deletions include/GeographicLib/Utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,18 @@ namespace GeographicLib {
static bool ParseLine(const std::string& line,
std::string& key, std::string& val);

/**
* Set the binary precision of a real number.
*
* @param[in] digits the number of bits of precision. If digits is 0 (the
* default), then determine the precision from the environment variable
* GEOGRAPHICLIB_DIGITS. If this is undefined, use digits = 256 (i.e.,
* about 77 decimal digits).
*
* This only has an effect when GEOGRAPHICLIB_PRECISION == 5.
**********************************************************************/
static void set_digits(int digits = 0);

};

} // namespace GeographicLib
Expand Down
10 changes: 9 additions & 1 deletion man/ConicProj.pod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ConicProj -- perform conic projections

B<ConicProj> ( B<-c> | B<-a> ) I<lat1> I<lat2>
[ B<-l> I<lon0> ] [ B<-k> I<k1> ] [ B<-r> ]
[ B<-e> I<a> I<f> ]
[ B<-e> I<a> I<f> ] [ B<-p> I<prec> ]
[ B<--comment-delimiter> I<commentdelim> ]
[ B<--version> | B<-h> | B<--help> ]
[ B<--input-file> I<infile> | B<--input-string> I<instring> ]
Expand Down Expand Up @@ -82,6 +82,14 @@ is allowed for I<f>. (Also, if I<f> E<gt> 1, the flattening is set to
1/I<f>.) By default, the WGS84 ellipsoid is used, I<a> = 6378137 m,
I<f> = 1/298.257223563.

=item B<-p>

set the output precision to I<prec> (default 6). I<prec> is the number
of digits after the decimal point for lengths (in meters). For
latitudes and longitudes (in degrees), the number of digits after the
decimal point is I<prec> + 5. For the convergence (in degrees) and
scale, the number of digits after the decimal point is I<prec> + 6.

=item B<--comment-delimiter>

set the comment delimiter to I<commentdelim> (e.g., "#" or "//"). If
Expand Down
10 changes: 9 additions & 1 deletion man/GeodesicProj.pod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ GeodesicProj -- perform projections based on geodesics
=head1 SYNOPSIS

B<GeodesicProj> ( B<-z> | B<-c> | B<-g> ) I<lat0> I<lon0> [ B<-r> ]
[ B<-e> I<a> I<f> ]
[ B<-e> I<a> I<f> ] [ B<-p> I<prec> ]
[ B<--comment-delimiter> I<commentdelim> ]
[ B<--version> | B<-h> | B<--help> ]
[ B<--input-file> I<infile> | B<--input-string> I<instring> ]
Expand Down Expand Up @@ -68,6 +68,14 @@ is allowed for I<f>. (Also, if I<f> E<gt> 1, the flattening is set to
1/I<f>.) By default, the WGS84 ellipsoid is used, I<a> = 6378137 m,
I<f> = 1/298.257223563.

=item B<-p>

set the output precision to I<prec> (default 6). I<prec> is the number
of digits after the decimal point for lengths (in meters). For
latitudes, longitudes, and azimuths (in degrees), the number of digits
after the decimal point is I<prec> + 5. For the scale, the number of
digits after the decimal point is I<prec> + 6.

=item B<--comment-delimiter>

set the comment delimiter to I<commentdelim> (e.g., "#" or "//"). If
Expand Down
8 changes: 8 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ else ()
${PROJECT_SHARED_LIBRARIES} ${PROJECT_STATIC_LIBRARIES} PROPERTIES
VERSION "${LIBVERSIONFULL}" SOVERSION "${LIBVERSION}"
OUTPUT_NAME ${LIBNAME})
if (APPLE AND GEOGRAPHICLIB_PRECISION EQUAL 5)
if (GEOGRAPHICLIB_SHARED_LIB)
target_link_libraries (${PROJECT_SHARED_LIBRARIES} ${MPFR_LIBRARIES})
endif ()
if (GEOGRAPHICLIB_STATIC_LIB)
target_link_libraries (${PROJECT_STATIC_LIBRARIES} ${MPFR_LIBRARIES})
endif ()
endif ()
endif ()

# Specify where the library is installed, adding it to the export depends
Expand Down
16 changes: 16 additions & 0 deletions src/Utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* http://geographiclib.sourceforge.net/
**********************************************************************/

#include <cstdlib>
#include <GeographicLib/Utility.hpp>

namespace GeographicLib {
Expand Down Expand Up @@ -39,4 +40,19 @@ namespace GeographicLib {
return true;
}

void Utility::set_digits(int digits) {
#if GEOGRAPHICLIB_PRECISION != 5
(void)digits;
#else
if (digits <= 0) {
char* digitenv = getenv("GEOGRAPHICLIB_DIGITS");
if (digitenv)
digits = strtol(digitenv, NULL, 0);
if (digits <= 0)
digits = 256;
}
Math::set_digits(digits);
#endif
}

} // namespace GeographicLib
Loading

0 comments on commit f3971a0

Please sign in to comment.