[geographiclib] 01/08: Imported Upstream version 1.42

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Fri May 1 11:17:29 UTC 2015


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository geographiclib.

commit 25126b88f4ee332415ddc575a28046f441a6bf4e
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Fri May 1 12:31:05 2015 +0200

    Imported Upstream version 1.42
---
 00README.txt                                       |  30 +-
 AUTHORS                                            |   1 +
 CMakeLists.txt                                     |  90 ++--
 Makefile.in                                        |  19 +-
 NEWS                                               |  66 ++-
 aclocal.m4                                         | 134 +++++-
 cmake/CMakeLists.txt                               |   2 +-
 cmake/Makefile.in                                  |   2 +-
 compile                                            | 347 +++++++++++++++
 configure                                          | 169 +++++++-
 configure.ac                                       |  28 +-
 doc/GeographicLib.dox.in                           | 479 +++++++++++----------
 doc/Makefile.in                                    |   2 +-
 doc/NETGeographicLib.dox                           |   2 +-
 doc/doxyfile-c.in                                  |  12 -
 doc/doxyfile-for.in                                |  12 -
 doc/doxyfile-net.in                                |  12 -
 doc/doxyfile.in                                    |  18 +-
 doc/geodesic-c.dox                                 |  16 +-
 doc/geodesic-for.dox                               |  16 +-
 dotnet/Projections/Projections-vs13.csproj         |  10 +-
 examples/JacobiConformal.hpp                       |  51 ++-
 examples/Makefile.in                               |   2 +-
 include/GeographicLib/CassiniSoldner.hpp           |  21 +-
 include/GeographicLib/Config.h                     |   4 +-
 include/GeographicLib/Constants.hpp                |  29 +-
 include/GeographicLib/DMS.hpp                      |  79 ++--
 include/GeographicLib/Ellipsoid.hpp                |  14 +-
 include/GeographicLib/GeoCoords.hpp                |  17 +-
 include/GeographicLib/Geodesic.hpp                 |  20 +-
 include/GeographicLib/GeodesicExact.hpp            |  20 +-
 include/GeographicLib/Geoid.hpp                    |  20 +-
 include/GeographicLib/LambertConformalConic.hpp    |  14 +-
 include/GeographicLib/MGRS.hpp                     |   2 +-
 include/GeographicLib/Math.hpp                     | 167 ++++++-
 include/GeographicLib/PolarStereographic.hpp       |  28 +-
 include/GeographicLib/Rhumb.hpp                    |  38 +-
 include/GeographicLib/TransverseMercator.hpp       |  29 +-
 include/GeographicLib/TransverseMercatorExact.hpp  |  16 +-
 include/GeographicLib/UTMUPS.hpp                   |   2 +-
 include/GeographicLib/Utility.hpp                  |  21 +-
 include/Makefile.in                                |   2 +-
 include/Makefile.mk                                |   8 +-
 java/direct/pom.xml                                |   6 +-
 java/inverse/pom.xml                               |   6 +-
 java/planimeter/pom.xml                            |   6 +-
 java/pom.xml                                       | 131 ++++--
 .../main/java/net/sf/geographiclib/Geodesic.java   |   7 +-
 .../java/net/sf/geographiclib/GeodesicLine.java    |   7 +-
 .../java/net/sf/geographiclib/PolygonArea.java     |   7 +-
 .../java/net/sf/geographiclib/package-info.java    |  87 ++--
 legacy/C/geodesic.c                                |   2 +-
 legacy/C/geodesic.h                                |  27 +-
 legacy/Fortran/geoddirect.for                      |   5 +-
 legacy/Fortran/geodesic.for                        |   2 +-
 legacy/Fortran/geodinverse.for                     |   5 +-
 man/CartConvert.1                                  |   4 +-
 man/CartConvert.usage                              |   2 +-
 man/ConicProj.1                                    |   4 +-
 man/ConicProj.usage                                |   2 +-
 man/GeoConvert.1                                   |  35 +-
 man/GeoConvert.1.html                              |  23 +
 man/GeoConvert.pod                                 |  27 ++
 man/GeoConvert.usage                               |  30 +-
 man/GeodSolve.1                                    |   4 +-
 man/GeodSolve.usage                                |   2 +-
 man/GeodesicProj.1                                 |   4 +-
 man/GeodesicProj.usage                             |   2 +-
 man/GeoidEval.1                                    |   7 +-
 man/GeoidEval.1.html                               |   2 +-
 man/GeoidEval.pod                                  |   3 +-
 man/GeoidEval.usage                                |   3 +-
 man/Gravity.1                                      |   4 +-
 man/Gravity.usage                                  |   2 +-
 man/MagneticField.1                                |   4 +-
 man/MagneticField.usage                            |   2 +-
 man/Makefile.in                                    |   2 +-
 man/Planimeter.1                                   |   4 +-
 man/Planimeter.usage                               |   2 +-
 man/RhumbSolve.1                                   |   4 +-
 man/RhumbSolve.usage                               |   2 +-
 man/TransverseMercatorProj.1                       |   4 +-
 man/TransverseMercatorProj.usage                   |   2 +-
 man/dummy.1.in                                     |  15 +-
 man/script.8.in                                    |  24 +-
 matlab/CMakeLists.txt                              |  98 +----
 matlab/Makefile.am                                 | 184 ++++----
 matlab/Makefile.in                                 | 192 +++++----
 matlab/Makefile.mk                                 |  34 +-
 matlab/cassini_inv.m                               |  46 --
 matlab/ecc2flat.m                                  |  10 -
 matlab/flat2ecc.m                                  |   9 -
 matlab/geocentricforward.m                         |  36 --
 matlab/geocentricreverse.m                         |  37 --
 matlab/geodesicdirect.m                            |  51 ---
 matlab/geodesicinverse.m                           |  51 ---
 matlab/geodesicline.m                              |  54 ---
 matlab/geodproj.m                                  | 139 ------
 matlab/geographiclib-legacy/Contents.m             |  38 ++
 .../geocentricforward.cpp                          |   0
 matlab/geographiclib-legacy/geocentricforward.m    |  46 ++
 .../geocentricreverse.cpp                          |   0
 matlab/geographiclib-legacy/geocentricreverse.m    |  47 ++
 .../{ => geographiclib-legacy}/geodesicdirect.cpp  |   0
 matlab/geographiclib-legacy/geodesicdirect.m       |  50 +++
 .../{ => geographiclib-legacy}/geodesicinverse.cpp |   0
 matlab/geographiclib-legacy/geodesicinverse.m      |  49 +++
 matlab/{ => geographiclib-legacy}/geodesicline.cpp |   0
 matlab/geographiclib-legacy/geodesicline.m         |  52 +++
 .../geographiclibinterface.m                       |  55 +--
 matlab/{ => geographiclib-legacy}/geoidheight.cpp  |   0
 matlab/geographiclib-legacy/geoidheight.m          |  39 ++
 .../localcartesianforward.cpp                      |   0
 .../geographiclib-legacy/localcartesianforward.m   |  63 +++
 .../localcartesianreverse.cpp                      |   0
 .../geographiclib-legacy/localcartesianreverse.m   |  59 +++
 matlab/{ => geographiclib-legacy}/mgrsforward.cpp  |   4 +-
 matlab/geographiclib-legacy/mgrsforward.m          |  34 ++
 matlab/{ => geographiclib-legacy}/mgrsreverse.cpp  |   2 +-
 matlab/{ => geographiclib-legacy}/mgrsreverse.m    |  29 +-
 matlab/{ => geographiclib-legacy}/polygonarea.cpp  |   0
 matlab/geographiclib-legacy/polygonarea.m          |  42 ++
 .../{ => geographiclib-legacy}/utmupsforward.cpp   |   0
 matlab/{ => geographiclib-legacy}/utmupsforward.m  |  36 +-
 .../{ => geographiclib-legacy}/utmupsreverse.cpp   |   0
 matlab/geographiclib-legacy/utmupsreverse.m        |  36 ++
 matlab/geographiclib/Contents.m                    |  95 ++++
 matlab/{ => geographiclib}/cassini_fwd.m           |  46 +-
 matlab/geographiclib/cassini_inv.m                 |  41 ++
 matlab/{ => geographiclib}/defaultellipsoid.m      |   4 +-
 matlab/geographiclib/ecc2flat.m                    |  12 +
 matlab/{ => geographiclib}/eqdazim_fwd.m           |  35 +-
 matlab/{ => geographiclib}/eqdazim_inv.m           |  39 +-
 matlab/geographiclib/flat2ecc.m                    |  11 +
 matlab/{ => geographiclib}/gedistance.m            |  54 ++-
 matlab/{ => geographiclib}/gedoc.m                 |  65 ++-
 matlab/geographiclib/geocent_fwd.m                 |  61 +++
 matlab/geographiclib/geocent_inv.m                 | 151 +++++++
 matlab/{ => geographiclib}/geodarea.m              |  24 +-
 matlab/{ => geographiclib}/geoddistance.m          |  51 +--
 matlab/{ => geographiclib}/geoddoc.m               |  58 +--
 matlab/{ => geographiclib}/geodreckon.m            |  24 +-
 matlab/geographiclib/geoid_height.m                | 165 +++++++
 matlab/geographiclib/geoid_load.m                  |  53 +++
 matlab/{ => geographiclib}/gereckon.m              |  37 +-
 matlab/{ => geographiclib}/gnomonic_fwd.m          |  41 +-
 matlab/{ => geographiclib}/gnomonic_inv.m          |  46 +-
 matlab/geographiclib/loccart_fwd.m                 |  57 +++
 matlab/geographiclib/loccart_inv.m                 |  56 +++
 matlab/geographiclib/mgrs_fwd.m                    | 169 ++++++++
 matlab/geographiclib/mgrs_inv.m                    | 214 +++++++++
 matlab/geographiclib/polarst_fwd.m                 |  67 +++
 matlab/geographiclib/polarst_inv.m                 |  64 +++
 matlab/{ => geographiclib}/private/A1m1f.m         |   2 +-
 matlab/{ => geographiclib}/private/A2m1f.m         |   2 +-
 matlab/{ => geographiclib}/private/A3coeff.m       |   4 +-
 matlab/{ => geographiclib}/private/A3f.m           |   4 +-
 matlab/{ => geographiclib}/private/AngDiff.m       |   4 +-
 matlab/{ => geographiclib}/private/AngNormalize.m  |   4 +-
 matlab/{ => geographiclib}/private/AngNormalize2.m |   4 +-
 matlab/{ => geographiclib}/private/AngRound.m      |   4 +-
 matlab/{ => geographiclib}/private/C1f.m           |   2 +-
 matlab/geographiclib/private/C1pf.m                |  22 +
 matlab/{ => geographiclib}/private/C2f.m           |   2 +-
 matlab/{ => geographiclib}/private/C3coeff.m       |   4 +-
 matlab/{ => geographiclib}/private/C3f.m           |   4 +-
 matlab/{ => geographiclib}/private/C4coeff.m       |   4 +-
 matlab/{ => geographiclib}/private/C4f.m           |   4 +-
 matlab/{ => geographiclib}/private/G4coeff.m       |   5 +-
 matlab/geographiclib/private/GeoRotation.m         |  26 ++
 matlab/{ => geographiclib}/private/SinCosSeries.m  |  11 +-
 matlab/geographiclib/private/cbrtx.m               |   9 +
 matlab/{ => geographiclib}/private/cvmgt.m         |   8 +-
 matlab/geographiclib/private/eatanhe.m             |  13 +
 matlab/geographiclib/private/geoid_file.m          |  27 ++
 matlab/geographiclib/private/geoid_load_file.m     |  32 ++
 matlab/geographiclib/private/norm2.m               |  10 +
 matlab/{ => geographiclib}/private/sumx.m          |   4 +-
 matlab/geographiclib/private/swap.m                |   5 +
 matlab/geographiclib/private/tauf.m                |  22 +
 matlab/geographiclib/private/taupf.m               |  10 +
 matlab/geographiclib/projdoc.m                     |  76 ++++
 matlab/{ => geographiclib}/tranmerc_fwd.m          |  55 +--
 matlab/{ => geographiclib}/tranmerc_inv.m          |  68 +--
 matlab/geographiclib/utmups_fwd.m                  | 120 ++++++
 matlab/geographiclib/utmups_inv.m                  |  83 ++++
 matlab/geoidheight.m                               |  38 --
 matlab/localcartesianforward.m                     |  41 --
 matlab/localcartesianreverse.m                     |  41 --
 matlab/mgrsforward.m                               |  31 --
 matlab/polygonarea.m                               |  47 --
 matlab/private/C1pf.m                              |  22 -
 matlab/private/SinCosNorm.m                        |  10 -
 matlab/private/atanhee.m                           |  15 -
 matlab/private/cbrt.m                              |   9 -
 matlab/private/swap.m                              |   8 -
 matlab/utm_fwd.m                                   |  50 ---
 matlab/utm_inv.m                                   |  51 ---
 matlab/utmupsreverse.m                             |  33 --
 missing                                            |   4 +-
 pom.xml                                            |   3 +-
 python/Makefile.in                                 |   2 +-
 src/CassiniSoldner.cpp                             |   6 +-
 src/DMS.cpp                                        |  53 ++-
 src/Ellipsoid.cpp                                  |  30 +-
 src/GeoCoords.cpp                                  |   5 +-
 src/Geocentric.cpp                                 |   8 +-
 src/Geodesic.cpp                                   |  41 +-
 src/GeodesicExact.cpp                              |  50 ++-
 src/GeodesicLine.cpp                               |  12 +-
 src/GeodesicLineExact.cpp                          |  14 +-
 src/GeographicLib.pro                              |   3 +-
 src/Geoid.cpp                                      |   1 +
 src/LambertConformalConic.cpp                      |  50 +--
 src/LocalCartesian.cpp                             |   3 +-
 src/MagneticModel.cpp                              |   8 +-
 src/Makefile.am                                    |   1 +
 src/Makefile.in                                    |   8 +-
 src/Makefile.mk                                    |   3 +-
 src/Math.cpp                                       |  65 +++
 src/PolarStereographic.cpp                         |  41 +-
 src/Rhumb.cpp                                      |  41 +-
 src/TransverseMercator.cpp                         |  74 +---
 src/TransverseMercatorExact.cpp                    |  41 +-
 src/UTMUPS.cpp                                     |   2 +-
 tools/CMakeLists.txt                               | 292 +------------
 tools/Makefile.am                                  |   2 +-
 tools/Makefile.in                                  |   4 +-
 tools/{CMakeLists.txt => tests.cmake}              | 123 ++----
 windows/Geographic-vc10.vcxproj                    |   1 +
 windows/Geographic-vc10x.vcxproj                   |   1 +
 windows/Geographic-vc13n.vcxproj                   |   5 +-
 windows/Geographic-vc8.vcproj                      |   4 +
 windows/Geographic-vc9.vcproj                      |   4 +
 234 files changed, 4912 insertions(+), 3099 deletions(-)

diff --git a/00README.txt b/00README.txt
index baa6483..a8b5685 100644
--- a/00README.txt
+++ b/00README.txt
@@ -16,8 +16,8 @@ Files
     include/GeographicLib/ and src/
       Config.h.in, Config.h -- system dependent configuration
       Constants.hpp -- WGS84 constants
-      Math.hpp -- math routines
-      Utility.hpp -- I/O and date routines
+      Math.[ch]pp -- math routines
+      Utility.[ch]pp -- I/O and date routines
       Accumulator.[ch]pp -- quad precision adder
       PolarStereographic.[ch]pp -- polar stereographic projection
       TransverseMercator.[ch]pp -- transverse Mercator projection
@@ -51,6 +51,7 @@ Files
     examples/
       example-*.cpp -- simple usage examples for all the classes
       GeoidToGTX.cpp -- a parallelization example
+      JacobiConformal.[ch]pp -- mapping a triaxial ellipsoid
 
     tools/
       GeoConvert.cpp -- geographic conversion utility
@@ -78,7 +79,6 @@ Files
       GeoidEval-vc9.vcproj -- project for GeoidEval
       Gravity-vc9.vcproj -- project for Gravity
       MagneticField-vc9.vcproj -- project for MagneticField
-      also files for MS Studio 2005 (with vc8)
       also files for MS Studio 2010 (with vc10)
       NETGeographic-vc10.vcxproj -- project for .NET wrapper
 
@@ -89,25 +89,11 @@ Files
       geod.mac -- Maxima code for series approximations for Geodesic
       geodesic.mac -- Maxima code for geodesic problems
 
-    matlab/
-      geographiclibinterface.m -- Matlab code to compile Matlab interfaces
-      utmupsforward.{cpp,m} -- Matlab code to convert geographic to UTM/UPS
-      utmupsreverse.{cpp,m} -- Matlab code to convert UTM/UPS to geographic
-      mgrsforward.{cpp,m} -- Matlab code to convert UTM/UPS to MGRS
-      mgrsreverse.{cpp,m} -- Matlab code to convert MGRS to UTM/UPS
-      geodesicdirect.{cpp,m} -- Matlab code for the direct geodesic problem
-      geodesicinverse.{cpp,m} -- Matlab code for the inverse geodesic problem
-      geodesicline.{cpp,m} -- Matlab code for geodesic lines
-      geoidheight.{cpp,m} -- Matlab code to look up geoid heights
-      polygonarea.{cpp,m} -- Matlab code for polygon areas
-      geoddoc.m -- documentation for native Matlab geodesic routines
-      geodreckon.m -- native Matlab implementation of direct geodesic problem
-      geoddistance.m -- native Matlab implementation of inverse geodesic problem
-      geodarea.m -- native Matlab implementation of polygon area
-      defaultellipsoid.m, ecc2flat.m, flat2ecc.m -- auxiliary functions
-      geodproj.m -- documentation for geodesic projections
-      *_{fwd,inv}.m -- native Matlab implementation of geodesic projections
-      private/*.m -- internal functions for geodesic routines
+    matlab/geographiclib
+      *.m, private/*.m -- Matlab implementation of some classes
+
+    matlab/geographiclib-legacy
+      *.{m,cpp} -- legacy Matlab routines
 
     doc/
       doxyfile.in -- Doxygen config file
diff --git a/AUTHORS b/AUTHORS
index 01c6997..5195a9e 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -4,3 +4,4 @@ Mathieu Peyréga <mathieu.peyrega at gmail.com> (help with gravity models)
 Andrew MacIntyre <Andrew.MacIntyre at acma.gov.au> (python/setup.py)
 Skip Breidbach <skip.breidbach at sri.com> (maven support for Java)
 Scott Heiman <mrmtdew2 at outlook.com> (.NET wrappers + C# examples)
+Chris Bennight <chris at bennight.com> (deploying Java library)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1d19ca6..720ab40 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,7 +2,7 @@ project (GeographicLib)
 
 # Version information
 set (PROJECT_VERSION_MAJOR 1)
-set (PROJECT_VERSION_MINOR 41)
+set (PROJECT_VERSION_MINOR 42)
 set (PROJECT_VERSION_PATCH 0)
 set (PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
 if (PROJECT_VERSION_PATCH GREATER 0)
@@ -43,7 +43,7 @@ endif ()
 # The library version tracks the numbering given by libtool in the
 # autoconf set up.
 set (LIBVERSION_API 14)
-set (LIBVERSION_BUILD 14.0.2)
+set (LIBVERSION_BUILD 14.0.3)
 string (TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWER)
 string (TOUPPER ${PROJECT_NAME} PROJECT_NAME_UPPER)
 
@@ -171,29 +171,24 @@ else ()
   set (PROJECT_DEFINITIONS ${PROJECT_STATIC_DEFINITIONS})
 endif ()
 
-# (5) Compile the Matlab interfaces?  Skip Matlab compilation if OFF
-set (MATLAB_COMPILER OFF CACHE STRING
-  "Compiler for matlab/octave interface: mex or mkoctfile or OFF")
-set_property (CACHE MATLAB_COMPILER PROPERTY STRINGS "mex" "mkoctfile" OFF)
-
-# (6) Create the documentation?  This depends on whether doxygen can be
+# (5) Create the documentation?  This depends on whether doxygen can be
 # found.  If this is OFF, then links will be provided to the online
 # documentation on Sourceforge.
 option (GEOGRAPHICLIB_DOCUMENTATION
   "Use doxygen to create the documentation" OFF)
 
-# (7) Build .NET wrapper library NETGeographicLib.  This only applies to
+# (6) Build .NET wrapper library NETGeographicLib.  This only applies to
 # Windows.  Default is OFF, because, currently, most people don't use
 # this interface.
 option (BUILD_NETGEOGRAPHICLIB "Build NETGeographicLib library" OFF)
 
-# (8) Set the default "real" precision.  This should probably be left
+# (7) Set the default "real" precision.  This should probably be left
 # at 2 (double).
 set (GEOGRAPHICLIB_PRECISION 2 CACHE STRING
   "Precision: 1 = float, 2 = double, 3 = extended, 4 = quadruple, 5 = variable")
 set_property (CACHE GEOGRAPHICLIB_PRECISION PROPERTY STRINGS 1 2 3 4 5)
 
-# (9) When making a binary package, should we include the debug version
+# (8) When making a binary package, should we include the debug version
 # of the library?  This applies to MSVC only, because that's the
 # platform where debug and release compilations do not inter-operate.
 # It requires building as follows:
@@ -253,11 +248,11 @@ else ()
   # 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)
+  check_cxx_compiler_flag (${CXX11_FLAG} CXX11TEST)
+  if (NOT CXX11TEST)
     set (CXX11_FLAG "-std=c++0x")
-    check_cxx_compiler_flag (${CXX11_FLAG} CXX11TEST2)
-    if (NOT CXX11TEST2)
+    check_cxx_compiler_flag (${CXX11_FLAG} CXX11TEST)
+    if (NOT CXX11TEST)
       unset (CXX11_FLAG)
     endif ()
   endif ()
@@ -266,19 +261,19 @@ else ()
   endif ()
 endif ()
 
+include (CheckCXXSourceCompiles)
+set (CMAKE_REQUIRED_FLAGS "${CMAKE_CXX_FLAGS}")
 # 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);
+             std::fma(1.0, 2.0, 3.0) + std::isfinite(4.0) + std::isnan(0.0);
 }\n" CXX11_MATH)
 if (CXX11_MATH)
   add_definitions (-DGEOGRAPHICLIB_CXX11_MATH=1)
@@ -286,6 +281,23 @@ else ()
   add_definitions (-DGEOGRAPHICLIB_CXX11_MATH=0)
 endif ()
 
+# Check whether the C++11 static_assert macro is 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), a work-alike substitution are
+# used.
+check_cxx_source_compiles (
+  "#include <cmath>
+int main() {
+  static_assert(true, \"static assert test\");
+  return 0;
+}\n" CXX11_STATIC_ASSERT)
+if (CXX11_STATIC_ASSERT)
+  add_definitions (-DGEOGRAPHICLIB_HAS_STATIC_ASSERT=1)
+else ()
+  add_definitions (-DGEOGRAPHICLIB_HAS_STATIC_ASSERT=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)
@@ -322,7 +334,7 @@ elseif (GEOGRAPHICLIB_PRECISION EQUAL 4)
   endif ()
 elseif (GEOGRAPHICLIB_PRECISION EQUAL 5)
   if (CXX11_MATH)
-    # Install MPFR C++ version 3.5.9 or later from
+    # Install MPFR C++ version 3.6.2 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.
@@ -417,44 +429,6 @@ if (MAINTAINER)
   add_dependencies (distrib-all distrib-man)
 endif ()
 
-# Look for the tool to compile the Matlab interfaces.
-if (MATLAB_COMPILER)
-  if (GEOGRAPHICLIB_PRECISION EQUAL 2)
-    if (WIN32)
-      set (MATLAB_COMPILER_EXT ".bat")
-    else ()
-      set (MATLAB_COMPILER_EXT "")
-    endif ()
-    find_program (MEX "${MATLAB_COMPILER}${MATLAB_COMPILER_EXT}")
-    if (MATLAB_COMPILER MATCHES "mex")
-      get_filename_component (MATLABDIR "${MEX}" REALPATH)
-      get_filename_component (MATLABDIR "${MATLABDIR}" PATH)
-      find_program (MEXEXTPROG "mexext${MATLAB_COMPILER_EXT}"
-        PATHS "${MATLABDIR}")
-      execute_process (COMMAND "${MEXEXTPROG}"
-        OUTPUT_VARIABLE MEXEXT OUTPUT_STRIP_TRAILING_WHITESPACE)
-      set (MEXOPTIONS "-largeArrayDims")
-    else ()
-      set (MEXEXT "mex")
-      set (MEXOPTIONS "--mex")
-    endif ()
-    if (NOT MSVC)
-      # mex files are shared objects => require static lib to be built with
-      # position independent code
-      set (CMAKE_POSITION_INDEPENDENT_CODE ON)
-    endif ()
-    if (NOT MEX)
-      message (WARNING
-        "Cannot find Matlab compiler ${MATLAB_COMPILER}${MATLAB_COMPILER_EXT}")
-    elseif (NOT MEXEXT)
-      set (MEX OFF)
-      message (WARNING "Cannot determine extension for Matlab compiled code")
-    endif ()
-  else ()
-    message (WARNING "Build of Matlab interfaces only works with doubles")
-  endif ()
-endif ()
-
 # Set a default build type for single-configuration cmake generators if
 # no build type is set.
 if (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
@@ -538,7 +512,7 @@ set (CPACK_SOURCE_IGNORE_FILES
   "${PROJECT_SOURCE_DIR}/[^/]*\\\\.(html|kmz|pdf)\$"
   "${PROJECT_SOURCE_DIR}/(autogen|biblio|js-compress)\\\\.sh\$"
   "${PROJECT_SOURCE_DIR}/(geodesic-biblio.txt|makefile-admin|[^/]*\\\\.png)\$"
-  "${PROJECT_SOURCE_DIR}/matlab/matlab-.*blurb.txt\$" )
+  "${PROJECT_SOURCE_DIR}/matlab/.*blurb.txt\$" )
 set (CPACK_SOURCE_GENERATOR TGZ)
 
 set (CPACK_RESOURCE_FILE_LICENSE ${PROJECT_SOURCE_DIR}/LICENSE.txt)
diff --git a/Makefile.in b/Makefile.in
index 5b4f8c6..5f56b65 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994-2013 Free Software Foundation, Inc.
@@ -87,8 +87,8 @@ subdir = .
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/configure $(am__configure_deps) \
 	$(top_srcdir)/include/GeographicLib/Config-ac.h.in AUTHORS \
-	INSTALL NEWS config.guess config.sub depcomp install-sh \
-	missing ltmain.sh
+	INSTALL NEWS compile config.guess config.sub depcomp \
+	install-sh missing ltmain.sh
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -379,8 +379,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
 $(am__aclocal_m4_deps):
 
 include/GeographicLib/Config-ac.h: include/GeographicLib/stamp-h1
-	@if test ! -f $@; then rm -f include/GeographicLib/stamp-h1; else :; fi
-	@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) include/GeographicLib/stamp-h1; else :; fi
+	@test -f $@ || rm -f include/GeographicLib/stamp-h1
+	@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) include/GeographicLib/stamp-h1
 
 include/GeographicLib/stamp-h1: $(top_srcdir)/include/GeographicLib/Config-ac.h.in $(top_builddir)/config.status
 	@rm -f include/GeographicLib/stamp-h1
@@ -592,10 +592,16 @@ dist-xz: distdir
 	$(am__post_remove_distdir)
 
 dist-tarZ: distdir
+	@echo WARNING: "Support for shar distribution archives is" \
+	               "deprecated." >&2
+	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
 	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
 	$(am__post_remove_distdir)
 
 dist-shar: distdir
+	@echo WARNING: "Support for distribution archives compressed with" \
+		       "legacy program 'compress' is deprecated." >&2
+	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
 	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
 	$(am__post_remove_distdir)
 
@@ -637,9 +643,10 @@ distcheck: dist
 	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
 	  && am__cwd=`pwd` \
 	  && $(am__cd) $(distdir)/_build \
-	  && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+	  && ../configure \
 	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
 	    $(DISTCHECK_CONFIGURE_FLAGS) \
+	    --srcdir=.. --prefix="$$dc_install_base" \
 	  && $(MAKE) $(AM_MAKEFLAGS) \
 	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
 	  && $(MAKE) $(AM_MAKEFLAGS) check \
diff --git a/NEWS b/NEWS
index 40764ce..8fac5e7 100644
--- a/NEWS
+++ b/NEWS
@@ -4,7 +4,61 @@ For more information, see
 
     http://geographiclib.sourceforge.net/
 
-The current version of the library is 1.41.
+The current version of the library is 1.42.
+
+Changes between 1.42 (released 2015-04-28) and 1.41 versions:
+
+  * DMS::Decode allows a single addition or subtraction operation, e.g.,
+    70W+0:0:15.  This affects the GeoCoords class and the utilities
+    (which use the DMS class for reading coordinates).
+
+  * Add Math::norm, Math::AngRound, Math::tand, Math::atan2d,
+    Math::eatanhe, Math::taupf, Math::tauf, Math::fma and remove
+    duplicated (but private) functionality from other classes.
+
+  * On non-Windows systems, the cmake config-style find_package files
+    are now installed under ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}
+    instead of ${CMAKE_INSTALL_PREFIX}/share, because the files are
+    architecture-specific.  This change will let 32-bit and 64-bit
+    versions coexist on the same machine (in lib and lib64).  You should
+    remove the versions in the old "share" location.
+
+  * MATLAB changes:
+    + provide native MATLAB implementations for compiled interface
+      functions;
+    + the compiled MATLAB interface is now deprecated and so the
+      MATLAB_COMPILER option in the cmake build has been removed;
+    + reorganize directories, so that
+      o matlab/geographiclib contains the native matlab code;
+      o matlab/geographiclib-legacy contains wrapper functions to mimic
+        the previous compiled functionality;
+    + the installed MATLAB code mirrors this layout, but the parent
+      installation directory on non-Windows systems is
+      ${CMAKE_INSTALL_PREFIX}/share (instead of
+      ${CMAKE_INSTALL_PREFIX}/libexec), because the files are now
+      architecture independent;
+    + matlab/geographiclib is now packaged and distributed as MATLAB
+      File Exchange package 50605 (this supersedes three earlier MATLAB
+      packages);
+    + point fix for geodarea.m to correct bug in area of polygons which
+      encircle a pole multiple times (released as version 1.41.1 of
+      MATLAB File Exchange package 39108, 2014-04-22).
+
+  * artifactId for Java package changed from GeographicLib to
+    GeographicLib-Java and the package is now depolyed to Maven Central
+    (thanks to Chris Bennight for help on this).
+
+  * Fix autoconf mismatch of version numbers (which were inconsistent in
+    versions 1.40 and 1.41).
+
+  * Mark the computation of the gradient of the geoid height in the
+    Geoid class and the <a href="GeoidEval.1.html">GeoidEval</a> utility
+    as deprecated.
+
+  * Work around the boost-quadmath bug with setprecision(0).
+
+  * Deprecate use of Visual Studio 2005 "-vc8" project files in the
+    windows directory.
 
 Changes between 1.41 (released 2015-03-09) and 1.40 versions:
 
@@ -47,11 +101,11 @@ Changes between 1.40 (released 2014-12-18) and 1.39 versions:
     http://geographiclib.sourceforge.net/cgi-bin/RhumbSolve.
 
   * Additions to the documentation:
-     + documentation on  Jacobi's conformal projection;
-     + a page on Auxiliary latitudes (actually, this was added in
-       version 1.39);
-     + document the use of two single quotes to stand for a double quote
-       in DMS (this feature was introduced in version 1.13).
+    + documentation on  Jacobi's conformal projection;
+    + a page on Auxiliary latitudes (actually, this was added in
+      version 1.39);
+    + document the use of two single quotes to stand for a double quote
+      in DMS (this feature was introduced in version 1.13).
 
   * The Matlab function, geographiclibinterface, which compiles the
     wrapper routines for Matlab now works with Matlab 2014b on a Mac.
diff --git a/aclocal.m4 b/aclocal.m4
index 37b3854..574d513 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,4 +1,4 @@
-# generated automatically by aclocal 1.13.4 -*- Autoconf -*-
+# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
 
 # Copyright (C) 1996-2013 Free Software Foundation, Inc.
 
@@ -26,7 +26,7 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
 #
 # SYNOPSIS
 #
-#   AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
+#   AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
 #
 # DESCRIPTION
 #
@@ -41,6 +41,8 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
 #   the flags: "CFLAGS EXTRA-FLAGS FLAG".  This can for example be used to
 #   force the compiler to issue an error when a bad flag is given.
 #
+#   INPUT gives an alternative input source to AC_COMPILE_IFELSE.
+#
 #   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
 #   macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
 #
@@ -75,19 +77,19 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
 #   modified version of the Autoconf Macro, you may extend this special
 #   exception to the GPL to apply to your modified version as well.
 
-#serial 2
+#serial 4
 
 AC_DEFUN([AX_CHECK_COMPILE_FLAG],
-[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
+[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
 AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
 AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
   ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
   _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
-  AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
+  AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
     [AS_VAR_SET(CACHEVAR,[yes])],
     [AS_VAR_SET(CACHEVAR,[no])])
   _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
-AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
+AS_VAR_IF(CACHEVAR,yes,
   [m4_default([$2], :)],
   [m4_default([$3], :)])
 AS_VAR_POPDEF([CACHEVAR])dnl
@@ -105,10 +107,10 @@ AS_VAR_POPDEF([CACHEVAR])dnl
 # generated from the m4 files accompanying Automake X.Y.
 # (This private macro should not be called outside this file.)
 AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.13'
+[am__api_version='1.14'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.13.4], [],
+m4_if([$1], [1.14.1], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -124,7 +126,7 @@ m4_define([_AM_AUTOCONF_VERSION], [])
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.13.4])dnl
+[AM_AUTOMAKE_VERSION([1.14.1])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
@@ -491,6 +493,12 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 # This macro actually does too much.  Some checks are only needed if
 # your package does certain things.  But this isn't really a big deal.
 
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
 # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
 # AM_INIT_AUTOMAKE([OPTIONS])
 # -----------------------------------------------
@@ -599,7 +607,48 @@ dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
 AC_CONFIG_COMMANDS_PRE(dnl
 [m4_provide_if([_AM_COMPILER_EXEEXT],
   [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
-])
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes.  So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+  cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present.  This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake at gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message.  This
+can help us improve future automake versions.
+
+END
+  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+    echo 'Configuration will proceed anyway, since you have set the' >&2
+    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+    echo >&2
+  else
+    cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+    AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+  fi
+fi])
 
 dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
 dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
@@ -607,7 +656,6 @@ dnl mangled by Autoconf and run in a shell conditional statement.
 m4_define([_AC_COMPILER_EXEEXT],
 m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
 
-
 # When config.status generates a header, we must update the stamp-h file.
 # This file resides in the same directory as the config header
 # that is generated.  The stamp files are numbered to have different names.
@@ -825,6 +873,70 @@ AC_DEFUN([_AM_SET_OPTIONS],
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake.  We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+  [whether $CC understands -c and -o together],
+  [am_cv_prog_cc_c_o],
+  [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+   ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   (exit $ac_status); }])
+
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
 # Copyright (C) 1996-2013 Free Software Foundation, Inc.
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
index 1a22c8e..cfe582a 100644
--- a/cmake/CMakeLists.txt
+++ b/cmake/CMakeLists.txt
@@ -21,7 +21,7 @@ export (TARGETS ${PROJECT_SHARED_LIBRARIES} ${PROJECT_STATIC_LIBRARIES} ${TOOLS}
 # path to the root from there.  (Note that the whole install tree can
 # be relocated.)
 if (COMMON_INSTALL_PATH)
-  set (INSTALL_CMAKE_DIR "share/cmake/${PROJECT_NAME}")
+  set (INSTALL_CMAKE_DIR "lib${LIB_SUFFIX}/cmake/${PROJECT_NAME}")
   set (PROJECT_ROOT_DIR "../../..")
 else ()
   set (INSTALL_CMAKE_DIR "cmake")
diff --git a/cmake/Makefile.in b/cmake/Makefile.in
index 5622bae..67a8f11 100644
--- a/cmake/Makefile.in
+++ b/cmake/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994-2013 Free Software Foundation, Inc.
diff --git a/compile b/compile
new file mode 100755
index 0000000..531136b
--- /dev/null
+++ b/compile
@@ -0,0 +1,347 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-10-14.11; # UTC
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey at cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake at gnu.org> or send patches to
+# <automake-patches at gnu.org>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" ""	$nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+  file=$1
+  case $file in
+    / | /[!/]*) # absolute file, and not a UNC file
+      if test -z "$file_conv"; then
+	# lazily determine how to convert abs files
+	case `uname -s` in
+	  MINGW*)
+	    file_conv=mingw
+	    ;;
+	  CYGWIN*)
+	    file_conv=cygwin
+	    ;;
+	  *)
+	    file_conv=wine
+	    ;;
+	esac
+      fi
+      case $file_conv/,$2, in
+	*,$file_conv,*)
+	  ;;
+	mingw/*)
+	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+	  ;;
+	cygwin/*)
+	  file=`cygpath -m "$file" || echo "$file"`
+	  ;;
+	wine/*)
+	  file=`winepath -w "$file" || echo "$file"`
+	  ;;
+      esac
+      ;;
+  esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+  func_file_conv "$1"
+  if test -z "$lib_path"; then
+    lib_path=$file
+  else
+    lib_path="$lib_path;$file"
+  fi
+  linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+  lib=$1
+  found=no
+  save_IFS=$IFS
+  IFS=';'
+  for dir in $lib_path $LIB
+  do
+    IFS=$save_IFS
+    if $shared && test -f "$dir/$lib.dll.lib"; then
+      found=yes
+      lib=$dir/$lib.dll.lib
+      break
+    fi
+    if test -f "$dir/$lib.lib"; then
+      found=yes
+      lib=$dir/$lib.lib
+      break
+    fi
+    if test -f "$dir/lib$lib.a"; then
+      found=yes
+      lib=$dir/lib$lib.a
+      break
+    fi
+  done
+  IFS=$save_IFS
+
+  if test "$found" != yes; then
+    lib=$lib.lib
+  fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+  # Assume a capable shell
+  lib_path=
+  shared=:
+  linker_opts=
+  for arg
+  do
+    if test -n "$eat"; then
+      eat=
+    else
+      case $1 in
+	-o)
+	  # configure might choose to run compile as 'compile cc -o foo foo.c'.
+	  eat=1
+	  case $2 in
+	    *.o | *.[oO][bB][jJ])
+	      func_file_conv "$2"
+	      set x "$@" -Fo"$file"
+	      shift
+	      ;;
+	    *)
+	      func_file_conv "$2"
+	      set x "$@" -Fe"$file"
+	      shift
+	      ;;
+	  esac
+	  ;;
+	-I)
+	  eat=1
+	  func_file_conv "$2" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-I*)
+	  func_file_conv "${1#-I}" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-l)
+	  eat=1
+	  func_cl_dashl "$2"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-l*)
+	  func_cl_dashl "${1#-l}"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-L)
+	  eat=1
+	  func_cl_dashL "$2"
+	  ;;
+	-L*)
+	  func_cl_dashL "${1#-L}"
+	  ;;
+	-static)
+	  shared=false
+	  ;;
+	-Wl,*)
+	  arg=${1#-Wl,}
+	  save_ifs="$IFS"; IFS=','
+	  for flag in $arg; do
+	    IFS="$save_ifs"
+	    linker_opts="$linker_opts $flag"
+	  done
+	  IFS="$save_ifs"
+	  ;;
+	-Xlinker)
+	  eat=1
+	  linker_opts="$linker_opts $2"
+	  ;;
+	-*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+	*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+	  func_file_conv "$1"
+	  set x "$@" -Tp"$file"
+	  shift
+	  ;;
+	*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+	  func_file_conv "$1" mingw
+	  set x "$@" "$file"
+	  shift
+	  ;;
+	*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+      esac
+    fi
+    shift
+  done
+  if test -n "$linker_opts"; then
+    linker_opts="-link$linker_opts"
+  fi
+  exec "$@" $linker_opts
+  exit 1
+}
+
+eat=
+
+case $1 in
+  '')
+     echo "$0: No command.  Try '$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake at gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "compile $scriptversion"
+    exit $?
+    ;;
+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+    func_cl_wrapper "$@"      # Doesn't return...
+    ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+  if test -n "$eat"; then
+    eat=
+  else
+    case $1 in
+      -o)
+	# configure might choose to run compile as 'compile cc -o foo foo.c'.
+	# So we strip '-o arg' only if arg is an object.
+	eat=1
+	case $2 in
+	  *.o | *.obj)
+	    ofile=$2
+	    ;;
+	  *)
+	    set x "$@" -o "$2"
+	    shift
+	    ;;
+	esac
+	;;
+      *.c)
+	cfile=$1
+	set x "$@" "$1"
+	shift
+	;;
+      *)
+	set x "$@" "$1"
+	shift
+	;;
+    esac
+  fi
+  shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+  # If no '-o' option was seen then we might have been invoked from a
+  # pattern rule where we don't need one.  That is ok -- this is a
+  # normal compilation that the losing compiler can handle.  If no
+  # '.c' file was seen then we are probably linking.  That is also
+  # ok.
+  exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+  if mkdir "$lockdir" >/dev/null 2>&1; then
+    break
+  fi
+  sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/configure b/configure
index 1db0215..aba964f 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for GeographicLib 1.41.
+# Generated by GNU Autoconf 2.69 for GeographicLib 1.42.
 #
 # Report bugs to <charles at karney.com>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='GeographicLib'
 PACKAGE_TARNAME='geographiclib'
-PACKAGE_VERSION='1.41'
-PACKAGE_STRING='GeographicLib 1.41'
+PACKAGE_VERSION='1.42'
+PACKAGE_STRING='GeographicLib 1.42'
 PACKAGE_BUGREPORT='charles at karney.com'
 PACKAGE_URL=''
 
@@ -1343,7 +1343,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures GeographicLib 1.41 to adapt to many kinds of systems.
+\`configure' configures GeographicLib 1.42 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1414,7 +1414,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of GeographicLib 1.41:";;
+     short | recursive ) echo "Configuration of GeographicLib 1.42:";;
    esac
   cat <<\_ACEOF
 
@@ -1525,7 +1525,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-GeographicLib configure 1.41
+GeographicLib configure 1.42
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1966,7 +1966,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by GeographicLib $as_me 1.41, which was
+It was created by GeographicLib $as_me 1.42, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2457,7 +2457,7 @@ test -n "$target_alias" &&
 
 
 
-am__api_version='1.13'
+am__api_version='1.14'
 
 # Find a good install program.  We prefer a C program (faster),
 # so one script is as good as another.  But avoid the broken or
@@ -2943,7 +2943,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='geographiclib'
- VERSION='1.41'
+ VERSION='1.42'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -2994,9 +2994,50 @@ am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
 
 
 
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes.  So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+  cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present.  This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake at gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message.  This
+can help us improve future automake versions.
+
+END
+  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+    echo 'Configuration will proceed anyway, since you have set the' >&2
+    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+    echo >&2
+  else
+    cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+    as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+  fi
+fi
 
 GEOGRAPHICLIB_VERSION_MAJOR=1
-GEOGRAPHICLIB_VERSION_MINOR=39
+GEOGRAPHICLIB_VERSION_MINOR=42
 GEOGRAPHICLIB_VERSION_PATCH=0
 
 cat >>confdefs.h <<_ACEOF
@@ -3045,7 +3086,7 @@ ac_config_headers="$ac_config_headers include/GeographicLib/Config-ac.h"
 
 
 LT_CURRENT=14
-LT_REVISION=2
+LT_REVISION=3
 LT_AGE=0
 
 
@@ -3904,6 +3945,65 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+   ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
 depcc="$CC"   am_compiler_list=
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
@@ -15450,8 +15550,40 @@ $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
  esac
 
 
-# Check flag for C++11
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts -std=c++0x" >&5
+# Check flags for C++11
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts -std=c++11" >&5
+$as_echo_n "checking whether C++ compiler accepts -std=c++11... " >&6; }
+if ${ax_cv_check_cxxflags___std_cpp11+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CXXFLAGS
+  CXXFLAGS="$CXXFLAGS  -std=c++11"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ax_cv_check_cxxflags___std_cpp11=yes
+else
+  ax_cv_check_cxxflags___std_cpp11=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CXXFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cxxflags___std_cpp11" >&5
+$as_echo "$ax_cv_check_cxxflags___std_cpp11" >&6; }
+if test "x$ax_cv_check_cxxflags___std_cpp11" = xyes; then :
+  CXXFLAGS="$CXXFLAGS -std=c++11"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts -std=c++0x" >&5
 $as_echo_n "checking whether C++ compiler accepts -std=c++0x... " >&6; }
 if ${ax_cv_check_cxxflags___std_cpp0x+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -15480,12 +15612,14 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cxxflags___std_cpp0x" >&5
 $as_echo "$ax_cv_check_cxxflags___std_cpp0x" >&6; }
-if test x"$ax_cv_check_cxxflags___std_cpp0x" = xyes; then :
+if test "x$ax_cv_check_cxxflags___std_cpp0x" = xyes; then :
   CXXFLAGS="$CXXFLAGS -std=c++0x"
 else
   :
 fi
 
+fi
+
 # Check for C++11 math functions
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -15495,7 +15629,8 @@ 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);
+                    std::fma(1.0, 2.0, 3.0) + std::cbrt(8.0)) +
+                    std::isfinite(4.0) + std::isnan(0.0);
   ;
   return 0;
 }
@@ -16243,7 +16378,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by GeographicLib $as_me 1.41, which was
+This file was extended by GeographicLib $as_me 1.42, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -16309,7 +16444,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-GeographicLib config.status 1.41
+GeographicLib config.status 1.42
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index 8c9baa4..e41f991 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
 dnl
 dnl Copyright (C) 2009, Francesco P. Lovergine <frankie at debian.org>
 
-AC_INIT([GeographicLib],[1.41],[charles at karney.com])
+AC_INIT([GeographicLib],[1.42],[charles at karney.com])
 AC_CANONICAL_SYSTEM
 AC_PREREQ(2.61)
 AC_CONFIG_SRCDIR(src/Geodesic.cpp)
@@ -9,14 +9,14 @@ AC_CONFIG_MACRO_DIR(m4)
 AM_INIT_AUTOMAKE
 
 GEOGRAPHICLIB_VERSION_MAJOR=1
-GEOGRAPHICLIB_VERSION_MINOR=39
+GEOGRAPHICLIB_VERSION_MINOR=42
 GEOGRAPHICLIB_VERSION_PATCH=0
 AC_DEFINE_UNQUOTED([GEOGRAPHICLIB_VERSION_MAJOR],
-	[$GEOGRAPHICLIB_VERSION_MAJOR],[major version number])
+        [$GEOGRAPHICLIB_VERSION_MAJOR],[major version number])
 AC_DEFINE_UNQUOTED([GEOGRAPHICLIB_VERSION_MINOR],
-	[$GEOGRAPHICLIB_VERSION_MINOR],[minor version number])
+        [$GEOGRAPHICLIB_VERSION_MINOR],[minor version number])
 AC_DEFINE_UNQUOTED([GEOGRAPHICLIB_VERSION_PATCH],
-	[$GEOGRAPHICLIB_VERSION_PATCH],[patch number])
+        [$GEOGRAPHICLIB_VERSION_PATCH],[patch number])
 AC_SUBST(GEOGRAPHICLIB_VERSION_MAJOR)
 AC_SUBST(GEOGRAPHICLIB_VERSION_MINOR)
 AC_SUBST(GEOGRAPHICLIB_VERSION_PATCH)
@@ -35,7 +35,7 @@ dnl Interfaces changed/added/removed:   CURRENT++ REVISION=0
 dnl Interfaces added:                   AGE++
 dnl Interfaces removed:                 AGE=0
 LT_CURRENT=14
-LT_REVISION=2
+LT_REVISION=3
 LT_AGE=0
 AC_SUBST(LT_CURRENT)
 AC_SUBST(LT_REVISION)
@@ -55,15 +55,19 @@ AC_TYPE_LONG_DOUBLE
 # Check endianness
 AC_C_BIGENDIAN
 
-# Check flag for C++11
-AX_CHECK_COMPILE_FLAG([-std=c++0x], [CXXFLAGS="$CXXFLAGS -std=c++0x"])
+# Check flags for C++11
+AX_CHECK_COMPILE_FLAG([-std=c++11],
+        [CXXFLAGS="$CXXFLAGS -std=c++11"],
+        [AX_CHECK_COMPILE_FLAG([-std=c++0x],
+                [CXXFLAGS="$CXXFLAGS -std=c++0x"])])
 # Check for C++11 math functions
 AC_TRY_COMPILE([#include <cmath>],
-	[return int(std::hypot(3.0, 4.0) + std::expm1(0.5) +
+        [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);],
-	[CXXFLAGS="$CXXFLAGS -DGEOGRAPHICLIB_CXX11_MATH=1"],
-	[CXXFLAGS="$CXXFLAGS -DGEOGRAPHICLIB_CXX11_MATH=0"])
+                    std::fma(1.0, 2.0, 3.0) + std::cbrt(8.0)) +
+                    std::isfinite(4.0) + std::isnan(0.0);],
+        [CXXFLAGS="$CXXFLAGS -DGEOGRAPHICLIB_CXX11_MATH=1"],
+        [CXXFLAGS="$CXXFLAGS -DGEOGRAPHICLIB_CXX11_MATH=0"])
 
 # Check for doxygen.
 AC_CHECK_PROGS([DOXYGEN], [doxygen])
diff --git a/doc/GeographicLib.dox.in b/doc/GeographicLib.dox.in
index fb4cd33..1bd0b69 100644
--- a/doc/GeographicLib.dox.in
+++ b/doc/GeographicLib.dox.in
@@ -12,7 +12,7 @@ namespace GeographicLib {
 \mainpage GeographicLib library
 \author Charles F. F. Karney (charles at karney.com)
 \version @PROJECT_VERSION@
-\date 2015-03-09
+\date 2015-04-28
 
 \section abstract Abstract
 
@@ -54,10 +54,10 @@ as either a compressed tar file (tar.gz) or a zip file.  (The two
 archives have identical contents, except that the zip file has DOS
 line endings.)  Alternatively you can get the latest release using git
 \verbatim
-  git clone -b r at PROJECT_VERSION@ git://git.code.sf.net/p/geographiclib/code geographiclib
+  git clone git://git.code.sf.net/p/geographiclib/code geographiclib
 \endverbatim
-There are also binary installers available for some platforms.  See \ref
-binaryinst.
+Each release is tagged, e.g., with r at PROJECT_VERSION@.  There are also
+binary installers available for some platforms.  See \ref binaryinst.
 
 GeographicLib is licensed under the
 <a href="http://www.opensource.org/licenses/MIT">MIT/X11 License</a>;
@@ -137,7 +137,7 @@ and the utilities have been tested with g++ 4.4 under Linux, with g++
 4.2 under Mac OS X, and with MS Visual Studio 9 (2008), 10 (2010), 11
 (2012), and 12 (2013) compiled for 32 bit and 64 bit.
 
-Matlab, JavaScript, and Python interfaces are provided to portions of
+MATLAB, JavaScript, and Python interfaces are provided to portions of
 GeographicLib; see \ref other.
 
 The section \ref geodesic documents the method of solving the geodesic
@@ -200,7 +200,7 @@ Then pick one of the first five options below:
 - \ref gnu.  This is a simple installation method that works with g++
   and GNU make on Linux and many Unix platforms.
 - \ref windows.  This is a simple installation method that works with
-  Visual Studio 2005, 2008, and 2010 under Windows.
+  Visual Studio 2008 and 2010 under Windows.
 - \ref binaryinst.  Use this installation method if you only need to use
   the \ref utilities supplied with GeographicLib.  (This method also
   installs the header files and the library for use by Visual Studio 10.)
@@ -299,9 +299,9 @@ Here are the steps to compile and install GeographicLib:
     matlab interfaces all depend on the variable with deeper paths
     relative to CMAKE_INSTALL_PREFIX being used when it's ON:
     - documentation: OFF: doc/html; ON: share/doc/GeographicLib/html;
-    - cmake configuration: OFF cmake; ON: share/cmake/GeographicLib;
+    - cmake configuration: OFF cmake; ON: lib/cmake/GeographicLib;
     - python interface: OFF: python; ON: lib/python/site-packages;
-    - matlab interface: OFF: matlab; ON: libexec/GeographicLib/matlab;
+    - matlab interface: OFF: matlab; ON: share/matlab;
     .
   - <code>CMAKE_INSTALL_PREFIX</code> (default: <code>/usr/local</code>
     on non-Windows systems, <code>C:/Program Files/GeographicLib</code>
@@ -338,10 +338,6 @@ Here are the steps to compile and install GeographicLib:
 \endverbatim
     (With IDE compile environments, you get to select the build type in
     the IDE.)
-  - <code>MATLAB_COMPILER</code> (default: OFF).  Set this to either
-    "mex" (for Matlab) or "mkoctfile" (for Octave) to specify the
-    compiler to use for the Matlab/Octave interface.  See \ref matlab
-    for more information.
   - <code>GEOGRAPHICLIB_DOCUMENTATION</code> (default: OFF).  If set to
     ON, then html documentation is created from the source files,
     provided a sufficiently recent version of doxygen can be found.
@@ -374,7 +370,6 @@ Here are the steps to compile and install GeographicLib:
   make install # as root, if CMAKE_INSTALL_PREFIX is a system directory
 \endverbatim
   Possible additional targets are \verbatim
-  make matlabinterface (only for the Release configuration on Windows)
   make dist
   make exampleprograms
   make netexamples (supported only for Release configuration) \endverbatim
@@ -424,11 +419,7 @@ Here are the steps to compile and install GeographicLib:
   make install \endverbatim
 - The headers, library, and utilities are installed in the
   include/GeographicLib, lib, and bin directories under
-  <code>prefix</code>.  This installation method does not compile
-  the Matlab/Octave interface;  however the source for the interface is
-  installed in libexec/GeographicLib/matlab, see \ref matlab of
-  instructions on compiling the interface.  For documentation, open
-  <a href="index.html">
+  <code>prefix</code>.  For documentation, open <a href="index.html">
   share/doc/GeographicLib/html/index.html</a> in a web browser.
 
 \section gnu Installation with GNU compiler and Make
@@ -457,34 +448,28 @@ Here are the steps to compile and install GeographicLib:
   make PREFIX=/tmp/geographic install \endverbatim
 - The headers, library, and utilities are installed in the
   include/GeographicLib, lib, and bin directories under
-  <code>PREFIX</code>.  This installation method does not compile
-  the Matlab/Octave interface;  however the source for the interface is
-  installed in libexec/GeographicLib/matlab, see \ref matlab of
-  instructions on compiling the interface.  For documentation, open
-  <a href="index.html">
+  <code>PREFIX</code>.  For documentation, open <a href="index.html">
   share/doc/GeographicLib/html/index.html</a> in a web browser.
 
 \section windows Installation on Windows
 
-This method requires Visual Studio 2005, 2008, or 2010.  This builds a
-static library and the utilities.  If you only have Visual Studio 2003,
-use cmake to create the necessary solution file, see \ref cmake.  (cmake
-is needed to build the Matlab interface and to run the tests.)
+This method requires Visual Studio 2008 or 2010.  This builds a static
+library and the utilities.  If you have some other version of Visual
+Studio, use cmake to create the necessary solution file, see \ref cmake.
+(cmake is needed to run the tests.)
 - Unpack the source, running \verbatim
   unzip -q GeographicLib- at PROJECT_VERSION@.zip \endverbatim
 - Open GeographicLib- at PROJECT_VERSION@/windows/GeographicLib-vc10.sln in
-  Visual Studio 2010 (for Visual Studio 2005 and 2008, replace -vc10 by
-  -vc8 or -vc9; for Visual Studio Express 2010, replace -vc10 by
-  -vc10x).
+  Visual Studio 2010 (for Visual Studio 2008, replace -vc10 by -vc9; for
+  Visual Studio Express 2010, replace -vc10 by -vc10x).
 - Pick the build type (e.g., Release), and select "Build Solution".
 - The library and the compiled examples are in the windows/Release.
 - Copy the library windows/Release/GeographicLib.lib and the
   headers in include/GeographicLib somewhere convenient.  The
   headers should remain in a directory named GeographicLib.  If you
-  expect to use the Matlab/Octave interface, copy *.m and *.cpp from the
-  matlab directory to a directory in your matlab/octave path, see \ref
-  matlab for instructions on compiling the interface.  For
-  documentation, open
+  expect to use the MATLAB/Octave interface, copy *.m from the matlab
+  directory to a directory in your matlab/octave path, see \ref matlab
+  for instructions on compiling the interface.  For documentation, open
   <a href="index.html">doc/html/index.html</a> in a web
   browser.
 
@@ -523,13 +508,12 @@ documentation for the library and for the utilities (and a link for
 uninstalling the library).  If you ask for your PATH to be modified, it
 will include C:/pkg-vc11/GeographicLib- at PROJECT_VERSION@/bin where the
 utilities are installed.  The headers and library are installed in the
-include/GeographicLib and lib folders.  With the 64-bit installer, the
-Matlab interface is installed in the matlab folder.  Add this to your
-path in Matlab to access this interface.  The libraries were built using
-using Visual Studio 11 2012 in release and debug modes.  The utilities
-were linked against the release-mode shared library.  The Matlab
-interface was compiled with Matlab R2013a 64-bit, however it may work
-with some other 64-bit versions of Matlab.
+include/GeographicLib and lib folders.  The MATLAB interface is
+installed in the matlab folder.  Add this to your path in MATLAB to
+access this interface.  The libraries were built using using Visual
+Studio 11 2012 in release and debug modes.  The utilities were linked
+against the release-mode shared library.
+
 <a href="NET/index.html">NETGeographicLib</a> library dlls (release and
 debug) are included with the binary installers; these are linked against
 the shared library for GeographicLib.
@@ -628,7 +612,6 @@ installer is created with \verbatim
   cmake -G "Visual Studio 10 Win64" \
     -D GEOGRAPHICLIB_LIB_TYPE=BOTH \
     -D PACKAGE_DEBUG_LIBS=ON \
-    -D MATLAB_COMPILER=mex \
     -D BUILD_NETGEOGRAPHICLIB=ON \
     ..
   cmake --build . --config Debug --target ALL_BUILD
@@ -1124,7 +1107,7 @@ returned as appropriate.  "INV" is treated as an invalid zone
 designation by UTMUPS.  "INVALID" is the corresponding invalid MGRS
 string.  (Similary "nan" is the equivalent invalid Geohash.)  NaNs allow
 the projection of polylines which are separated by NaNs; in this format
-they can be easily plotted in Matlab.
+they can be easily plotted in MATLAB.
 
 A note about portability.  For the most part, the code uses standard C++
 and should be able to be deployed on any system with a modern C++
@@ -1159,10 +1142,14 @@ starting in version 1.31.  There's also a macro
 GEOGRAPHICLIB_VERSION_STRING which expands to, e.g.,
 "@PROJECT_VERSION@"; this macro has been defined since version 1.9.
 Since version 1.37, there's also been a macro GEOGRAPHICLIB_VERSION
-which encode the version as a single number, e.g, 1003900.  The macro
-GEOGRAPHICLIB_VERSION_NUM allows you to compare versions, e.g., \code
-#if GEOGRAPHICLIB_VERSION >= GEOGRAPHICLIB_VERSION_NUM(1,36,0)
-... \endcode
+which encodes the version as a single number, e.g, 1003900.  Do not rely
+on this particular packing; instead use the macro
+GEOGRAPHICLIB_VERSION_NUM(a,b,c) which allows you to compare versions
+with, e.g.,
+\code
+#if GEOGRAPHICLIB_VERSION >= GEOGRAPHICLIB_VERSION_NUM(1,37,0)
+...
+#endif \endcode
 
 <center>
 Back to \ref utilities.  Forward to \ref other.  Up to \ref contents.
@@ -1207,6 +1194,17 @@ self-contained and does not depend on the rest of GeographicLib.  Sample
 main programs to solve the direct and inverse geodesic problems and to
 compute polygonal areas are provided.
 
+This package is available on Maven Central; so if you're using Apache
+Maven as your build system, you can use this package by including the
+dependency \verbatim
+  <dependency>
+    <groupId>net.sf.geographiclib</groupId>
+    <artifactId>GeographicLib-Java</artifactId>
+    <version>1.42</version>
+  </dependency>
+  \endverbatim
+in your <code>pom.xml</code>.
+
 For documentation, see
  - <a href="java/index.html">Java library for geodesics</a>.
 
@@ -1306,160 +1304,130 @@ print(h['lat2'], h['lon2']);
 (Note: The initial version of setup.py was provided by Andrew MacIntyre
 of the Australian Communications and Media Authority.)
 
-\section matlab Matlab and Octave implementations
+\section matlab MATLAB and Octave implementations
 
-The <code>matlab</code> directory Matlab and Octave implementations of
-some of the functions of GeographicLib.  To use
-these, start Matlab or Octave and run one of (for example) \verbatim
-   addpath /usr/local/libexec/GeographicLib/matlab
-   addpath 'C:/pkg-vc10-x64/GeographicLib- at PROJECT_VERSION@/libexec/GeographicLib/matlab'
+The <code>matlab/geographiclib</code> directory contains MATLAB and
+Octave implementations of some of the functions of GeographicLib.  To
+use these, start MATLAB or Octave and run one of (for example):
+\verbatim
+   addpath /usr/local/share/matlab/geographiclib
+   addpath C:/pkg-vc10-x64/GeographicLib- at PROJECT_VERSION@/matlab/geographiclib
    \endverbatim
+A summary of the routines is obtained by \verbatim
+   help geographiclib \endverbatim
+These MATLAB functions is also available from the MATLAB File Exchange
+site as the
+<a href="http://www.mathworks.com/matlabcentral/fileexchange/50605">
+GeographicLib toolbox</a>, package 50605.
 
 The functions fall into the following groups
+ - Geodesics
+   - geoddistance     - Distance between points on an ellipsoid
+   - geodreckon       - Point at specified azimuth, range on an ellipsoid
+   - geodarea         - Surface area of polygon on an ellipsoid
+ - Projections
+   - tranmerc_fwd     - Forward transverse Mercator projection
+   - tranmerc_inv     - Inverse transverse Mercator projection
+   - polarst_fwd      - Forward polar stereographic projection
+   - polarst_inv      - Inverse polar stereographic projection
+   - eqdazim_fwd      - Forward azimuthal equidistant projection
+   - eqdazim_inv      - Inverse azimuthal equidistant projection
+   - cassini_fwd      - Forward Cassini-Soldner projection
+   - cassini_inv      - Inverse Cassini-Soldner projection
+   - gnomonic_fwd     - Forward ellipsoidal gnomonic projection
+   - gnomonic_inv     - Inverse ellipsoidal gnomonic projection
+ - Grid systems
+   - utmups_fwd       - Convert to UTM/UPS system
+   - utmups_inv       - Convert from UTM/UPS system
+   - mgrs_fwd         - Convert UTM/UPS coordinates to MGRS
+   - mgrs_inv         - Convert MGRS to UTM/UPS coordinates
+ - Geoid lookup
+   - geoid_height     - Compute the height of the geoid
+   - geoid_load       - Load a geoid model
+ - Great ellipses
+   - gedistance       - Great ellipse distance between points on an ellipsoid
+   - gereckon         - Point along great ellipse at specified azimuth and range
+ - Geometric transformations
+   - geocent_fwd      - Conversion from geographic to geocentric coordinates
+   - geocent_inv      - Conversion from geocentric to geographic coordinates
+   - loccart_fwd      - Convert geographic to local cartesian coordinates
+   - loccart_inv      - Convert local cartesian to geographic coordinates
+ - Utility
+   - defaultellipsoid - Return the WGS84 ellipsoid
+   - ecc2flat         - Convert eccentricity to flattening
+   - flat2ecc         - Convert flattening to eccentricity
+ - Documentation
+   - geoddoc          - Geodesics on an ellipsoid of revolution
+   - projdoc          - Geodesic projections for an ellipsoid
+   - gedoc            - Great ellipses on an ellipsoid of revolution
+ .
+These functions reimplement the C++ routines from GeographicLib in
+MATLAB code (but note that routines for great ellipses are <i>only</i>
+available as MATLAB code).  Because these functions are all vectorized,
+their performance is comparable to the C++ routines.  The minimum
+version numbers required are
+ - MATLAB, version 7.9, 2009b,
+ - Octave, version 3.4, Feb. 2011.
+ .
+In addition, in order to use the geoid routines, Octave needs to have
+been built with a version of GraphicsMagick which supports 16-bit
+images.
+
+Previously, some of these routines were packaged as three separate
+packages
  - <a href="http://www.mathworks.com/matlabcentral/fileexchange/39108">
-   Geodesics on an ellipsoid of revolution</a>, native Matlab
-   implementations of the geodesic routines.  The available functions
-   are
-   - geoddoc: briefly descibe the routines
-   - geodreckon: solve the direct geodesic problem
-   - geoddistance: solve the inverse geodesic problem
-   - geodarea: compute the area of ellipsoidal polygons
-   .
-   Use the help function to get documentation, e.g., \code
-   help geoddistance \endcode
-   to obtain documentation.  These functions are also available as a
-   Matlab File Exchange package from
-   - <a href="http://www.mathworks.com/matlabcentral/fileexchange/39108">
-     http://www.mathworks.com/matlabcentral/fileexchange/39108</a>
+   Geodesics on an ellipsoid of revolution</a>,
+   MATLAB File Exchange package 39108.
  - <a href="http://www.mathworks.com/matlabcentral/fileexchange/39366">
-   Geodesic projections for an ellipsoid</a>, native Matlab
-   implementations of projections which are related to geodesics.  These
-   are
-   - geodproj: briefly descibe the routines
-   - eqdazim_fwd, eqdazim_inv: azimuthal equidistant
-   - cassini_fwd, cassini_inv: Cassini-Soldner
-   - tranmerc_fwd, tranmerc_inv: transverse Mercator
-   - gnomonic_fwd, gnomonic_inv: ellipsoidal gnomonic
-   - utm_fwd, utm_inv: universal transverse Mercator
-   .
-   These functions are also available as a Matlab File Exchange package
-   from
-   - <a href="http://www.mathworks.com/matlabcentral/fileexchange/39366">
-     http://www.mathworks.com/matlabcentral/fileexchange/39366</a>
-   .
-   (This requires that the previous package also be installed.)
+   Geodesic projections for an ellipsoid</a>,
+   MATLAB File Exchange package 39366,
  - <a href="http://www.mathworks.com/matlabcentral/fileexchange/47898">
-   Great ellipses</a>, implementations of solutions to the great ellipse
-   problems.  The functions are
-   - gedoc: briefly descibe the routines
-   - gereckon: solve the direct great circle problem
-   - gedistance: solve the inverse great circle problem
-   .
-   The functionality provided by these routines is <i>not</i> available
-   through GeographicLib's C++ library.  These functions are also
-   available as a Matlab File Exchange package from
-   - <a href="http://www.mathworks.com/matlabcentral/fileexchange/47898">
-     http://www.mathworks.com/matlabcentral/fileexchange/47898</a>
-   .
-   (This requires that package 39108 also be installed.)  Background on
-   this problem is provided in \ref greatellipse.
- - Finally, interface code so that some GeographicLib classes can be
-   accessed directly from Matlab or Octave.  The rest of this section
-   describes how to compile and use these interfaces.
-
-There are two ways of compiling the interface code: (1) using cmake and
-(2) invoking the compiler from Matlab.
- - <b>Using cmake:</b> (Only tested on Linux and Windows.) Before
-   running cmake, configure MATLAB on Windows to use the same compiler
-   that you're going to use for compiling GeographicLib.  For example
-   \verbatim
-   mex.bat -setup
-
-   Please choose your compiler for building MEX-files:
-   Would you like mex to locate installed compilers [y]/n? y
-   Select a compiler:
-   [1] Microsoft Visual C++ 2012 in C:\Program Files (x86)\Microsoft Visual Studio 11.0
-   [2] Microsoft Visual C++ 2010 in C:\Program Files (x86)\Microsoft Visual Studio 10.0
-
-   [0] None
-
-   Compiler: 2
-   etc. \endverbatim
-   (This will require that mex.bat is in your PATH.  With Linux, use
-   <code>mex -setup</code>.)  Then configure cmake with, for example
-   \verbatim
-   cmake -G "Visual Studio 10" -D MATLAB_COMPILER=mex ..
-   cmake --build . --config Release --target matlabinterface \endverbatim
-   (Note that only the Release configuration is supported for Matlab.)
-   If you are running a 64-bit version of Matlab, be sure to select a
-   64-bit generator with cmake, e.g., "Visual Studio 10 Win64".  Finally
-   compile GeographicLib with Visual Studio.  (The binary installer for
-   64-bit Windows includes the compiled interface built with Visual
-   Studio 10 and Matlab R2013a 64-bit).<br>
-   On Linux systems, you can compile the interface for use with octave
-   instead by using \verbatim
-   cmake -D MATLAB_COMPILER=mkoctfile ..
-   make matlabinterface \endverbatim
- - <b>Invoking the compiler from Matlab or Octave:</b> (Tested with
-   Linux, Mac OSX, and Windows.)  Start Matlab or Octave and run, e.g.,
-   \code
-   mex -setup
-   cd 'C:/pkg-vc10-x64/GeographicLib- at PROJECT_VERSION@/matlab'
-   help geographiclibinterface
-   geographiclibinterface('C:/pkg-vc10/GeographicLib- at PROJECT_VERSION@');
-   addpath(pwd);
-   \endcode
-   The first command allows you to select the compiler to use (which
-   should be the same as that used to compile GeographicLib).  On Mac
-   OSX and Matlab R2014b, the setup command is \code
-   mex -setup C++
-   \endcode
-
-To use the interface routines for GeographicLib, run one of (for
-example) \verbatim
-  addpath /usr/local/libexec/GeographicLib/matlab
-  addpath 'C:/pkg-vc10-x64/GeographicLib- at PROJECT_VERSION@/libexec/GeographicLib/matlab'
-\endverbatim
-in Octave or Matlab.  The available functions are:
- - geodesicdirect: solve direct geodesic problem
-   (see Geodesic::Direct)
- - geodesicinverse: solve inverse geodesic problem
-   (see Geodesic::Inverse)
- - geodesicline: compute points along a geodesic
-   (see GeodesicLine::Position)
- - polygonarea: compute area of a geodesic polygon
-   (see PolygonAreaT)
- - utmupsforward: convert geographic coordinates to UTM/UPS
-   (see UTMUPS::Forward)
- - utmupsreverse: convert UTM/UPS coordinates to geographic
-   (see UTMUPS::Reverse)
- - mgrsforward: convert UTM/UPS coordinates to MGRS
-   (see MGRS::Forward)
- - mgrsreverse: convert MGRS coordinates to UTM/UPS
-   (see MGRS::Reverse)
- - geoidheight: compute geoid height
-   (see Geoid::operator()())
- - geocentricforward: convert geographic coordinates to geocentric
-   (see Geocentric::Forward)
- - geocentricreverse: convert geocentric coordinates to geographic
-   (see Geocentric::Reverse)
- - localcartesianforward: convert geographic coordinates to local cartesian
-   (see LocalCartesian::Forward)
- - localcartesianreverse: convert local cartesian coordinates to geographic
-   (see LocalCartesian::Reverse)
+   Great ellipses</a>,
+   MATLAB File Exchange package 47898.
  .
-These routines just offer a simple interface to the corresponding C++
-class.  Use the help function to get documentation, e.g., \code
-  help geodesicdirect \endcode
-Unfortunately, the help function does not work for compiled functions in
-Octave; in this case, just list the .m file, e.g., \code
-  type geodesicdirect \endcode
-Other useful functions, e.g., to convert from geographic
-coordinates to MGRS can easily be written with Matlab code.
-
-Note that geoidheight, when compiled with Visual Studio 2008 causes
-Matlab to crash.  (The problem does not occur with Visual Studio 2005 or
-Visual Studio 2010.)
+These packages have now all been incorporated into the
+<a href="http://www.mathworks.com/matlabcentral/fileexchange/50605">
+GeographicLib toolbox</a>.
+
+Prior to version 1.42, GeographicLib was distributed with some MATLAB
+functionality offered via compiled interface code.  This has now been
+replaced by native MATLAB wrapper functions which call the functions in
+the <a href="http://www.mathworks.com/matlabcentral/fileexchange/50605">
+GeographicLib toolbox</a>.  To use these wrapper functions, run one of:
+\verbatim
+   addpath /usr/local/share/matlab/geographiclib-legacy
+   addpath C:/pkg-vc10-x64/GeographicLib- at PROJECT_VERSION@/matlab/geographiclib-legacy
+   \endverbatim
+The <a href="http://www.mathworks.com/matlabcentral/fileexchange/50605">
+GeographicLib toolbox</a> <i>must</i> also be in your MATLAB path.  A
+summary of the routines is obtained by \verbatim
+   help geographiclib-legacy \endverbatim
+These functions are <b>DEPRECATED</b>.  Here is a function listing
+  - Geodesics
+    - geodesicdirect         - Wrapper for geodreckon
+    - geodesicinverse        - Wrapper for geoddistance
+    - geodesicline           - Another wrapper for geodreckon
+    - polygonarea            - Wrapper for geodarea
+  - Grid systems
+    - utmupsforward          - Wrapper for utmups_fwd
+    - utmupsreverse          - Wrapper for utmups_inv
+    - mgrsforward            - Wrapper for mgrs_fwd
+    - mgrsreverse            - Wrapper for mgrs_inv
+  - Geoid lookup
+    - geoidheight            - Wrapper for geoid_height
+  - Geometric transformations
+    - geocentricforward      - Wrapper for geocent_fwd
+    - geocentricreverse      - Wrapper for geocent_inv
+    - localcartesianforward  - Wrapper for loccart_fwd
+    - localcartesianreverse  - Wrapper for loccart_inv
+  - Deprecated
+    - geographiclibinterface - Compile interface code (DEPRECATED)
+  .
+The last routine can be used to compile the obsolete interface code
+(which is still provided as C++ code in the same directory).  Doing this
+will switch MATLAB from using the native MATLAB routines to the compiled
+interface.  However, the native code is easier to deploy and is about as
+fast; so the compiled interface will be removed at some point in 2016.
 
 \section maxima Maxima routines
 
@@ -4418,9 +4386,10 @@ Back to \ref triaxial.  Forward to \ref rhumb.  Up to
 
 In addition to solving the geodesic problem for the triaxial ellipsoid,
 Jacobi (1839) briefly mentions the problem of the conformal projection
-of ellipsoid.  He covers this in greater detail in <i>Vorlesungen
-über Dynamik</i>, §28, which is now available in an
-<a href="https://www.worldcat.org/oclc/440645889">
+of ellipsoid.  He covers this in greater detail in
+<a href="https://books.google.com/books?id=ryEOAAAAQAAJ&pg=PA212">
+<i>Vorlesungen über Dynamik</i>, §28</a>, which is now
+available in an <a href="https://www.worldcat.org/oclc/440645889">
 English translation: Lectures on Dynamics</a>
 (<a href="http://geographiclib.sf.net/jacobi-errata.html">
 errata</a>).
@@ -4705,8 +4674,9 @@ standard construction in the limit of an ellipsoid of revolution.
 
 \section jacobi-implementation An implementation of the projection
 
-An implementation of the Jacobi conformal projection is given here
-\include JacobiConformal.hpp
+The JacobiConformal class provides an implementation of the Jacobi
+conformal projection is given here.  <b>NOTE:</b> This is just sample
+code.  It is not part of GeographicLib itself.
 
 <center>
 Back to \ref triaxial.  Forward to \ref rhumb.  Up to \ref contents.
@@ -5323,19 +5293,14 @@ geodesic problems is complex and costly.  These assumptions are no
 longer true, and geodesics should normally be used in place of great
 ellipses.  This is discussed in more detail in \ref gevsgeodesic.
 
-Solutions of the great ellipse problems implemented for Matlab and
+Solutions of the great ellipse problems implemented for MATLAB and
 Octave are provided by
  - gedoc: briefly descibe the routines
  - gereckon: solve the direct great circle problem
  - gedistance: solve the inverse great circle problem
  .
-These functions are also available as a package
-<a href="http://www.mathworks.com/matlabcentral/fileexchange/47898">
-47898</a> on Matlab File Exchange.  This requires also the installation
-of package
-<a href="http://www.mathworks.com/matlabcentral/fileexchange/39108">
-39108</a>.  In this time, there are no C++ support in GeographicLib for
-great ellipses.
+At this time, there are no C++ support in GeographicLib for great
+ellipses.
 
 References:
  - P. D. Thomas,
@@ -6736,12 +6701,13 @@ Here's what you should know:
  - Configuring with <code>-D GEOGRAPHICLIB_PRECISION=4</code> gives quad
    precision (113-bit precision) via boost::multiprecision::float128;
    this requires <a href="http://www.boost.org"> boost</a> (version 1.54
-   or later) and the quadmath library (which requires the use of g++).
+   or later) and the quadmath library (the package names are libquadmath
+   and libquadmath-devel).  This requires the use of g++.
  - Configuring with <code>-D GEOGRAPHICLIB_PRECISION=5</code> gives
    arbitrary precision via mpfr::mpreal; this requires
    <a href="http://www.mpfr.org"> MPFR</a> (version 3.0 or later),
    <a href="http://www.holoborodko.com/pavel/mpfr"> MPFR C++</a>
-   (version 3.5.9 or later), and a compiler which supports the explicit
+   (version 3.6.2 or later), and a compiler which supports the explicit
    cast operator (e.g., g++ 4.5 or later, Visual Studio 12 2013 or
    later).
  - MPFR, MPFR C++, and Boost all come with their own licenses.  Be sure
@@ -7008,6 +6974,53 @@ of the
 <a href="https://sourceforge.net/p/geographiclib/code/ci/release/tree/">
 git repository for GeographicLib</a>.
 
+ - <a href="http://geographiclib.sf.net/1.42">Version 1.42</a>
+   (released 2015-04-28)
+   - DMS::Decode allows a single addition or subtraction operation,
+     e.g., 70W+0:0:15.  This affects the GeoCoords class and the
+     utilities (which use the DMS class for reading coordinates).
+   - Add Math::norm, Math::AngRound, Math::tand, Math::atan2d,
+     Math::eatanhe, Math::taupf, Math::tauf, Math::fma and remove
+     duplicated (but private) functionality from other classes.
+   - On non-Windows systems, the cmake config-style find_package files
+     are now installed under ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}
+     instead of ${CMAKE_INSTALL_PREFIX}/share, because the files are
+     architecture-specific.  This change will let 32-bit and 64-bit
+     versions coexist on the same machine (in lib and lib64).  You
+     should remove the versions in the old "share" location.
+   - MATLAB changes:
+     - provide native MATLAB implementations for compiled interface
+       functions, see \ref matlab;
+     - the compiled MATLAB interface is now deprecated and so the
+       MATLAB_COMPILER option in the cmake build has been removed;
+     - reorganize directories, so that
+       - matlab/geographiclib contains the native matlab code;
+       - matlab/geographiclib-legacy contains wrapper functions to mimic
+         the previous compiled functionality;
+     - the installed MATLAB code mirrors this layout, but the parent
+       installation directory on non-Windows systems is
+       ${CMAKE_INSTALL_PREFIX}/share (instead of
+       ${CMAKE_INSTALL_PREFIX}/libexec), because the files are now
+       architecture independent;
+     - matlab/geographiclib is now packaged and distributed as
+       MATLAB File Exchange package
+       <a href="http://www.mathworks.com/matlabcentral/fileexchange/50605">
+       50605</a> (this supersedes three earlier MATLAB packages);
+     - point fix for geodarea.m to correct bug in area of polygons which
+       encircle a pole multiple times (released as version 1.41.1 of
+       MATLAB File Exchange package 39108, 2014-04-22).
+   - artifactId for Java package changed from GeographicLib to
+     GeographicLib-Java and the package is now depolyed to
+     Maven Central (thanks to Chris Bennight for help on this).
+   - Fix autoconf mismatch of version numbers (which were inconsistent
+     in versions 1.40 and 1.41).
+   - Mark the computation of the gradient of the geoid height in the
+     Geoid class and the <a href="GeoidEval.1.html">GeoidEval</a>
+     utility as deprecated.
+   - Work around the boost-quadmath bug with setprecision(0).
+   - Deprecate use of Visual Studio 2005 "-vc8" project files in the
+     windows directory.
+
  - <a href="http://geographiclib.sf.net/1.41">Version 1.41</a>
    (released 2015-03-09)
    - Fix bug in Rhumb::Inverse (with \e exact = true) and related
@@ -7029,7 +7042,7 @@ git repository for GeographicLib</a>.
    - Geodesic::Inverse didn't return NaN if one of the longitudes was a
      NaN (bug introduced in version 1.25).  Fixed in the C++, Java,
      JavaScript, C, Fortran, and Python implementations of the geodesic
-     routines.  This bug was not present in the Matlab version.
+     routines.  This bug was not present in the MATLAB version.
    - Fix bug in Utility::readarray and Utility::writearray which caused
      an exception in debug mode with zero-sized arrays.
    - Fix BLUNDER in OSGB::GridReference (found by kalderami) where the
@@ -7046,8 +7059,8 @@ git repository for GeographicLib</a>.
      - a page on \ref auxlat (actually, this was added in version 1.39);
      - document the use of two single quotes to stand for a double quote
        in DMS (this feature was introduced in version 1.13).
-   - The Matlab function, geographiclibinterface, which compiles the
-     wrapper routines for Matlab now works with Matlab on a Mac.
+   - The MATLAB function, geographiclibinterface, which compiles the
+     wrapper routines for MATLAB now works with MATLAB on a Mac.
 
  - <a href="http://geographiclib.sf.net/1.39">Version 1.39</a>
    (released 2014-11-11)
@@ -7060,7 +7073,7 @@ git repository for GeographicLib</a>.
        arguments for Geodesic, GeodesicLine, Rhumb, and RhumbLine;
      - similar changes have been made to the Python, Javascript, and
        Java implementations of the geodesic routines;
-     - for the C, Fortran, and Matlab implementations the \e arcmode
+     - for the C, Fortran, and MATLAB implementations the \e arcmode
        argument to the routines was generalized to allow a combination
        of ARCMODE and LONG_NOWRAP bits;
      - the Maxima version now returns the longitude unwrapped.
@@ -7077,14 +7090,14 @@ git repository for GeographicLib</a>.
      - add PolygonAreaRhumb typedef for PolygonAreaT<Rhumb>;
      - add -R option to <a href="Planimeter.1.html">Planimeter</a> to use
        PolygonAreaRhumb (and -G option for the default geodesic polygon);
-     - fix BLUNDER in area calculation in Matlab routine geodreckon;
-     - add area calculation to Matlab/Octave routines for great ellipses
+     - fix BLUNDER in area calculation in MATLAB routine geodreckon;
+     - add area calculation to MATLAB/Octave routines for great ellipses
        (see \ref gearea).
    - Fix bad BUG in Geohash::Reverse; this was introduced in version
      1.37 and affected all platforms where unsigned longs are 32-bits.
      Thanks to Christian Csar for reporting and diagnosing this.
    - Binary installers for Windows are now built with Visual Studio 11
-     2012 (instead of Visual Studio 10 2010).  Compiled Matlab support
+     2012 (instead of Visual Studio 10 2010).  Compiled MATLAB support
      still with version 2013a (64-bit).
    - Update GeographicLib.pro for builds with qmake to include all the
      source files.
@@ -7111,7 +7124,7 @@ git repository for GeographicLib</a>.
    - Accept the minus sign as a synomym for - in DMS.{cpp,js}.
    - The cmake configuration file geographiclib-depends.cmake has been
      renamed to geographiclib-targets.cmake.
-   - Matlab/Octave routines for great ellipses added; see \ref
+   - MATLAB/Octave routines for great ellipses added; see \ref
      greatellipse.
    - Provide man pages for geographiclib-get-{geoids,gravity,magnetic}.
 
@@ -7120,7 +7133,7 @@ git repository for GeographicLib</a>.
    - Add \ref highprec.
    - <b>INCOMPATIBLE CHANGE</b>: the static instantiations of various
      classes for the WGS84 ellipsoid have been changed to a
-     <a href="http://www.parashift.com/c++-faq/static-init-order-on-first-use.html">
+     <a href="http://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use">
      "construct on first use idiom"</a>.  This avoids a lot of wasteful
      initialization before the user's code starts.  Unfortunately it
      means that existing source code that relies on any of the following
@@ -7234,7 +7247,7 @@ git repository for GeographicLib</a>.
    (released 2014-03-13)
    - Fix blunder in UTMUPS::EncodeEPSG (found by Ben
      Adler).
-   - Matlab wrapper routines geodesic{direct,inverse,line} switch to
+   - MATLAB wrapper routines geodesic{direct,inverse,line} switch to
      "exact" routes if |<i>f</i>| > 0.02.
    - GeodSolve.cgi allows ellipsoid to be set (and uses the -E option
      for <a href="GeodSolve.1.html">GeodSolve</a>).
@@ -7321,9 +7334,9 @@ git repository for GeographicLib</a>.
      - improving setting of runtime path for Unix-like systems with cmake;
      - install PDB files when compiling with Visual Studio to aid
        debugging;
-     - Windows binary release now uses Matlab R2013a (64-bit) and
+     - Windows binary release now uses MATLAB R2013a (64-bit) and
        uses the -largeArrayDims option.
-     - fixes to the way the Matlab interface routines are built (thanks
+     - fixes to the way the MATLAB interface routines are built (thanks
        to Phil Miller and Chris F.).
    - Changes to the geodesic routines:
      - add \ref java of the geodesic routines (thanks to Skip Breidbach
@@ -7333,7 +7346,7 @@ git repository for GeographicLib</a>.
      - fixes to python port so that they work with version 3.x, in
        addition to 2.x (courtesy of Amato);
      - accumulate the perimeter and area of polygons via a double-wide
-       accumulator in Fortran, C, and Matlab implementations (this is
+       accumulator in Fortran, C, and MATLAB implementations (this is
        already included in the other implementations);
      - port PolygonArea::AddEdge and
        PolygonArea::TestEdge to JavaScript and python
@@ -7347,7 +7360,7 @@ git repository for GeographicLib</a>.
    - Improve efficiency of MGRS::Forward by avoiding the
      calculation of the latitude if possible (adapting an idea of Craig
      Rollins).
-   - Fixes to the way the Matlab interface routines are built (thanks to
+   - Fixes to the way the MATLAB interface routines are built (thanks to
      Phil Miller and Chris F.).
 
  - <a href="http://geographiclib.sf.net/1.30">Version 1.30</a>
@@ -7373,7 +7386,7 @@ git repository for GeographicLib</a>.
        close to the prime meridian;
      - FIX BUG is geoddistance.m where the value of m12 was wrong for
        meridional geodesics;
-     - add Matlab implementations of the geodesic projections;
+     - add MATLAB implementations of the geodesic projections;
      - remove unneeded special code for geodesics which start at a pole;
      - include polygon area routine in C and Fortran implementations;
      - add doxygen documentation for C and Fortran libraries.
@@ -7381,7 +7394,7 @@ git repository for GeographicLib</a>.
  - <a href="http://geographiclib.sf.net/1.27">Version 1.27</a>
    (released 2012-11-29)
    - Changes to geodesic routines:
-     - add native Matlab implementations: geoddistance.m, geodreckon.m,
+     - add native MATLAB implementations: geoddistance.m, geodreckon.m,
        geodarea.m;
      - add C and Fortran implementations;
      - improve the solution of the direct problem so that the series
@@ -7502,7 +7515,7 @@ git repository for GeographicLib</a>.
      document this as the preferred method of using autoconf.
    - cmake tweaks:
      - simplify the configuration of doxygen;
-     - allow the Matlab compiler to be specified with the
+     - allow the MATLAB compiler to be specified with the
        MATLAB_COMPILER option.
 
  - <a href="http://geographiclib.sf.net/1.20">Version 1.20</a>
@@ -7523,14 +7536,14 @@ git repository for GeographicLib</a>.
    - Fix argument checking tests in MGRS::Forward.
    - Add \--comment-delimiter and \--line-separator options to the \ref
      utilities.
-   - Add installer for 64-bit Windows; the compiled Matlab interface is
+   - Add installer for 64-bit Windows; the compiled MATLAB interface is
      supplied with the Windows 64-bit installer only.
 
  - <a href="http://geographiclib.sf.net/1.18">Version 1.18</a>
    (released 2012-02-18)
    - Improve documentation on configuration with cmake.
    - cmake's find_package ensures that the compiler versions match on Windows.
-   - Improve documentation on compiling Matlab interface.
+   - Improve documentation on compiling MATLAB interface.
    - Binary installer for Windows installs under C:/pkg-vc10 by default.
 
  - <a href="http://geographiclib.sf.net/1.17">Version 1.17</a>
@@ -7646,11 +7659,11 @@ git repository for GeographicLib</a>.
  - <a href="http://geographiclib.sf.net/1.12">Version 1.12</a>
    (released 2011-07-21)
    - Change license to MIT/X11.
-   - Add PolygonArea class and equivalent Matlab function.
+   - Add PolygonArea class and equivalent MATLAB function.
    - Provide JavaScript and Python implementations of geodesic routines.
-   - Fix Windows installer to include runtime dlls for Matlab.
+   - Fix Windows installer to include runtime dlls for MATLAB.
    - Fix (innocuous) unassigned variable in Geodesic::GenInverse.
-   - Geodesic routines in Matlab return a12 as first column of aux return
+   - Geodesic routines in MATLAB return a12 as first column of aux return
      value (incompatible change).
    - A couple of code changes to enable compilation with Visual
      Studio 2003.
@@ -7684,7 +7697,7 @@ git repository for GeographicLib</a>.
 
  - <a href="http://geographiclib.sf.net/1.10">Version 1.10</a>
    (released 2011-06-11)
-   - Improvements to Matlab/Octave interface:
+   - Improvements to MATLAB/Octave interface:
      - add {geocentric,localcartesian}{forward,reverse};
      - make geographiclibinterface more general;
      - install the source for the interface;
@@ -7752,7 +7765,7 @@ git repository for GeographicLib</a>.
    - Library created by Visual Studio is Geographic.lib instead of
      GeographicLib.lib (compatible with makefiles).
    - Make classes NaN aware.
-   - Use cell arrays for MGRS strings in Matlab.
+   - Use cell arrays for MGRS strings in MATLAB.
    - Add solution/project files for Visual Studio 2010 (32-bit only).
    - Use C++11 static_assert and math functions, if available.
 
@@ -7774,7 +7787,7 @@ git repository for GeographicLib</a>.
      with previous versions of GeographicLib.  However, the library is
      source compatible.
    - Add OSGB.
-   - Matlab and Octave interfaces to UTMUPS,
+   - MATLAB and Octave interfaces to UTMUPS,
      MGRS, Geoid, Geodesic
      provided.
    - Minor changes
diff --git a/doc/Makefile.in b/doc/Makefile.in
index 519e65e..de41ff1 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994-2013 Free Software Foundation, Inc.
diff --git a/doc/NETGeographicLib.dox b/doc/NETGeographicLib.dox
index 0bc8aa8..d4cdf7c 100644
--- a/doc/NETGeographicLib.dox
+++ b/doc/NETGeographicLib.dox
@@ -14,7 +14,7 @@
 \version 1.40
 \date 2014-12-18
 
-\section abstract Abstract
+\section abstract-net Abstract
 
 %NETGeographicLib is a .NET wrapper for GeographicLib.  It allows
 .NET developers to access GeographicLib classes within C#, Visual
diff --git a/doc/doxyfile-c.in b/doc/doxyfile-c.in
index f0eef2b..030bab6 100644
--- a/doc/doxyfile-c.in
+++ b/doc/doxyfile-c.in
@@ -1398,18 +1398,6 @@ GENERATE_XML           = NO
 
 XML_OUTPUT             = xml
 
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_SCHEMA             =
-
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_DTD                =
-
 # If the XML_PROGRAMLISTING tag is set to YES Doxygen will
 # dump the program listings (including syntax highlighting
 # and cross-referencing information) to the XML output. Note that
diff --git a/doc/doxyfile-for.in b/doc/doxyfile-for.in
index d2490a2..4a1bdeb 100644
--- a/doc/doxyfile-for.in
+++ b/doc/doxyfile-for.in
@@ -1397,18 +1397,6 @@ GENERATE_XML           = NO
 
 XML_OUTPUT             = xml
 
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_SCHEMA             =
-
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_DTD                =
-
 # If the XML_PROGRAMLISTING tag is set to YES Doxygen will
 # dump the program listings (including syntax highlighting
 # and cross-referencing information) to the XML output. Note that
diff --git a/doc/doxyfile-net.in b/doc/doxyfile-net.in
index 500d66b..230b6b4 100644
--- a/doc/doxyfile-net.in
+++ b/doc/doxyfile-net.in
@@ -1399,18 +1399,6 @@ GENERATE_XML           = NO
 
 XML_OUTPUT             = xml
 
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_SCHEMA             =
-
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_DTD                =
-
 # If the XML_PROGRAMLISTING tag is set to YES Doxygen will
 # dump the program listings (including syntax highlighting
 # and cross-referencing information) to the XML output. Note that
diff --git a/doc/doxyfile.in b/doc/doxyfile.in
index 8882c86..dca5a53 100644
--- a/doc/doxyfile.in
+++ b/doc/doxyfile.in
@@ -139,7 +139,8 @@ STRIP_FROM_PATH        = @PROJECT_SOURCE_DIR@/
 # definition is used. Otherwise one should specify the include paths that
 # are normally passed to the compiler using the -I flag.
 
-STRIP_FROM_INC_PATH    = @PROJECT_SOURCE_DIR@/include/
+STRIP_FROM_INC_PATH    = @PROJECT_SOURCE_DIR@/include/ \
+                         @PROJECT_SOURCE_DIR@/examples/
 
 # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
 # (but less readable) file names. This can be useful if your file system
@@ -650,7 +651,8 @@ WARN_LOGFILE           =
 INPUT                  = @PROJECT_SOURCE_DIR@/src \
                          @PROJECT_SOURCE_DIR@/include/GeographicLib \
                          @PROJECT_SOURCE_DIR@/tools \
-                         @PROJECT_BINARY_DIR@/doc/GeographicLib.dox
+                         @PROJECT_BINARY_DIR@/doc/GeographicLib.dox \
+                         @PROJECT_SOURCE_DIR@/examples/JacobiConformal.hpp
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
@@ -1400,18 +1402,6 @@ GENERATE_XML           = NO
 
 XML_OUTPUT             = xml
 
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_SCHEMA             =
-
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_DTD                =
-
 # If the XML_PROGRAMLISTING tag is set to YES Doxygen will
 # dump the program listings (including syntax highlighting
 # and cross-referencing information) to the XML output. Note that
diff --git a/doc/geodesic-c.dox b/doc/geodesic-c.dox
index 2c4552e..a7f05c8 100644
--- a/doc/geodesic-c.dox
+++ b/doc/geodesic-c.dox
@@ -11,9 +11,9 @@
 /**
 \mainpage Geodesic routines implemented in C
 \author Charles F. F. Karney (charles at karney.com)
-\version 1.40
+\version 1.42
 
-\section abstract Abstract
+\section abstract-c Abstract
 
 This is a C implementation of the geodesic algorithms from <a
 href="http://geographiclib.sf.net">GeographicLib</a>.  This is a
@@ -24,16 +24,16 @@ B. W. Kernigan and D. M. Ritchie, The C Programming Language, 2nd
 Ed. (Prentice Hall, 1988), and so should compile correctly with just
 about any C compiler.
 
-\section download Downloading the source
+\section download-c Downloading the source
 
 The C library is part of %GeographicLib which available for download at
-- <a href="https://sf.net/projects/geographiclib/files/distrib/GeographicLib-1.40.tar.gz">
-  GeographicLib-1.40.tar.gz</a>
-- <a href="https://sf.net/projects/geographiclib/files/distrib/GeographicLib-1.40.zip">
-  GeographicLib-1.40.zip</a>
+- <a href="https://sf.net/projects/geographiclib/files/distrib/GeographicLib-1.42.tar.gz">
+  GeographicLib-1.42.tar.gz</a>
+- <a href="https://sf.net/projects/geographiclib/files/distrib/GeographicLib-1.42.zip">
+  GeographicLib-1.42.zip</a>
 .
 as either a compressed tar file (tar.gz) or a zip file.  After unpacking
-the source, the C library can be found in GeographicLib-1.40/legacy/C.
+the source, the C library can be found in GeographicLib-1.42/legacy/C.
 The library consists of two files geodesic.c and geodesic.h.
 
 The library is also included as part of
diff --git a/doc/geodesic-for.dox b/doc/geodesic-for.dox
index 8618aca..7d419d4 100644
--- a/doc/geodesic-for.dox
+++ b/doc/geodesic-for.dox
@@ -11,9 +11,9 @@
 /**
 \mainpage Geodesic routines implemented in Fortran
 \author Charles F. F. Karney (charles at karney.com)
-\version 1.40
+\version 1.42
 
-\section abstract Abstract
+\section abstract-for Abstract
 
 This is a Fortran implementation of the geodesic algorithms from <a
 href="http://geographiclib.sf.net">GeographicLib</a>.  This is a
@@ -22,17 +22,17 @@ for an ellipsoid of revolution in a Fortran program.  It is written in
 Fortran 77 (avoiding features which are now deprecated) and should
 compile correctly with just about any Fortran compiler.
 
-\section download Downloading the source
+\section download-for Downloading the source
 
 The Fortran library is part of %GeographicLib which available for download at
-- <a href="https://sf.net/projects/geographiclib/files/distrib/GeographicLib-1.40.tar.gz">
-  GeographicLib-1.40.tar.gz</a>
-- <a href="https://sf.net/projects/geographiclib/files/distrib/GeographicLib-1.40.zip">
-  GeographicLib-1.40.zip</a>
+- <a href="https://sf.net/projects/geographiclib/files/distrib/GeographicLib-1.42.tar.gz">
+  GeographicLib-1.42.tar.gz</a>
+- <a href="https://sf.net/projects/geographiclib/files/distrib/GeographicLib-1.42.zip">
+  GeographicLib-1.42.zip</a>
 .
 as either a compressed tar file (tar.gz) or a zip file.  After unpacking
 the source, the Fortran library can be found in
-GeographicLib-1.40/legacy/Fortran.  The library consists of the file
+GeographicLib-1.42/legacy/Fortran.  The library consists of the file
 geodesic.for.
 
 \section doc Library documentation
diff --git a/dotnet/Projections/Projections-vs13.csproj b/dotnet/Projections/Projections-vs13.csproj
index 0bb5f95..2f6f330 100644
--- a/dotnet/Projections/Projections-vs13.csproj
+++ b/dotnet/Projections/Projections-vs13.csproj
@@ -10,8 +10,9 @@
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>Projections</RootNamespace>
     <AssemblyName>Projections</AssemblyName>
-    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
-    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
     <FileAlignment>512</FileAlignment>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
@@ -23,6 +24,7 @@
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
     <PlatformTarget>x64</PlatformTarget>
@@ -33,6 +35,7 @@
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
     <PlatformTarget>x86</PlatformTarget>
@@ -42,6 +45,7 @@
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
     <PlatformTarget>x64</PlatformTarget>
@@ -51,6 +55,7 @@
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
   <ItemGroup>
     <Reference Include="System" />
@@ -251,6 +256,7 @@
     </ProjectReference>
   </ItemGroup>
   <ItemGroup>
+    <None Include="app.config" />
     <None Include="Properties\Settings.settings">
       <Generator>SettingsSingleFileGenerator</Generator>
       <LastGenOutput>Settings.Designer.cs</LastGenOutput>
diff --git a/examples/JacobiConformal.hpp b/examples/JacobiConformal.hpp
index 86f93d7..90e4809 100644
--- a/examples/JacobiConformal.hpp
+++ b/examples/JacobiConformal.hpp
@@ -1,6 +1,9 @@
 /**
  * \file JacobiConformal.hpp
- * \brief Jacobi's conformal projection of a triaxial ellipsoid.
+ * \brief Header for GeographicLib::JacobiConformal class
+ *
+ * <b>NOTE:</b> This is just sample code.  It is not part of GeographicLib
+ * itself.
  *
  * Copyright (c) Charles Karney (2014-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
@@ -11,17 +14,29 @@
 
 namespace GeographicLib {
   /**
-   * \brief Jacobi's conformal projection
+   * \brief Jacobi's conformal projection of a triaxial ellipsoid
+   *
+   * <b>NOTE:</b> This is just sample code.  It is not part of GeographicLib
+   * itself.
    *
    * This is a conformal projection of the ellipsoid to a plane in which
-   * the grid lines are straight; see Jacobi, Vorlesungen ueber Dynamik,
-   * Sect. 28.  The constructor takes the semi-axes of the ellipsoid (which
-   * must be in order).  Member functions map the ellipsoidal coordinates
-   * ω and β separately to \e x and \e y.  Jacobi's coordinates
-   * have been multiplied by
-   * (<i>a</i><sup>2</sub>−<i>c</i><sup>2</sub>)<sup>1/2</sup> /
+   * the grid lines are straight; see Jacobi,
+   * <a href="https://books.google.com/books?id=ryEOAAAAQAAJ&pg=PA212">
+   * Vorlesungen über Dynamik, §28</a>.  The constructor takes the
+   * semi-axes of the ellipsoid (which must be in order).  Member functions map
+   * the ellipsoidal coordinates ω and β separately to \e x and \e
+   * y.  Jacobi's coordinates have been multiplied by
+   * (<i>a</i><sup>2</sup>−<i>c</i><sup>2</sup>)<sup>1/2</sup> /
    * (2<i>b</i>) so that the customary results are returned in the cases of
    * a sphere or an ellipsoid of revolution.
+   *
+   * The ellipsoid is oriented so that the large principal ellipse, \f$Z=0\f$,
+   * is the equator, \f$\beta=0\f$, while the small principal ellipse,
+   * \f$Y=0\f$, is the prime meridian, \f$\omega=0\f$.  The four umbilic
+   * points, \f$\left|\omega\right| = \left|\beta\right| = \frac12\pi\f$, lie
+   * on middle principal ellipse in the plane \f$X=0\f$.
+   *
+   * For more information on this projection, see \ref jacobi.
    **********************************************************************/
   class JacobiConformal {
     typedef Math::real real;
@@ -33,9 +48,9 @@ namespace GeographicLib {
     /**
      * Constructor for a trixial ellipsoid with semi-axes
      *
-     * @param[in] a
-     * @param[in] b
-     * @param[in] c
+     * @param[in] a the largest semi-axis.
+     * @param[in] b the middle semi-axis.
+     * @param[in] c the smallest semi-axis.
      *
      * The semi-axes must satisfy \e a ≥ \e b ≥ \e c > 0 and \e a >
      * \e c.  This form of the constructor cannot be used to specify a
@@ -57,16 +72,16 @@ namespace GeographicLib {
         throw GeographicErr("JacobiConformal: use alternate constructor for sphere");
     }
     /**
-     * Alternate constructor for a triaxial ellipsoid with semi-axes
+     * Alternate constructor for a triaxial ellipsoid.
      *
-     * @param[in] a
-     * @param[in] b
-     * @param[in] c
-     * @param[in] ab the relative magnitude of \e a &minus \e b.
-     * @param[in] bc the relative magnitude of \e b &minus \e c.
+     * @param[in] a the largest semi-axis.
+     * @param[in] b the middle semi-axis.
+     * @param[in] c the smallest semi-axis.
+     * @param[in] ab the relative magnitude of \e a − \e b.
+     * @param[in] bc the relative magnitude of \e b − \e c.
      *
      * This form can be used to specify a sphere.  The semi-axes must
-     * satisfy \e a &ge \e b &ge c > 0.  The ratio \e ab : \e bc must equal
+     * satisfy \e a ≥ \e b ≥ c > 0.  The ratio \e ab : \e bc must equal
      * (<i>a</i>−<i>b</i>) : (<i>b</i>−<i>c</i>) with \e ab
      * ≥ 0, \e bc ≥ 0, and \e ab + \e bc > 0.
      **********************************************************************/
diff --git a/examples/Makefile.in b/examples/Makefile.in
index f59da88..eb83649 100644
--- a/examples/Makefile.in
+++ b/examples/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994-2013 Free Software Foundation, Inc.
diff --git a/include/GeographicLib/CassiniSoldner.hpp b/include/GeographicLib/CassiniSoldner.hpp
index e2fa558..fe25740 100644
--- a/include/GeographicLib/CassiniSoldner.hpp
+++ b/include/GeographicLib/CassiniSoldner.hpp
@@ -2,7 +2,7 @@
  * \file CassiniSoldner.hpp
  * \brief Header for GeographicLib::CassiniSoldner class
  *
- * Copyright (c) Charles Karney (2009-2011) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2009-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  **********************************************************************/
@@ -75,25 +75,6 @@ namespace GeographicLib {
     real _sbet0, _cbet0;
     static const unsigned maxit_ = 10;
 
-    // The following private helper functions are copied from Geodesic.
-    static inline real AngRound(real x) {
-      // The makes the smallest gap in x = 1/16 - nextafter(1/16, 0) = 1/2^57
-      // for reals = 0.7 pm on the earth if x is an angle in degrees.  (This
-      // is about 1000 times more resolution than we get with angles around 90
-      // degrees.)  We use this to avoid having to deal with near singular
-      // cases when x is non-zero but tiny (e.g., 1.0e-200).
-      using std::abs;
-      const real z = 1/real(16);
-      GEOGRAPHICLIB_VOLATILE real y = abs(x);
-      // The compiler mustn't "simplify" z - (z - y) to y
-      y = y < z ? z - (z - y) : y;
-      return x < 0 ? -y : y;
-    }
-    static inline void SinCosNorm(real& sinx, real& cosx) {
-      real r = Math::hypot(sinx, cosx);
-      sinx /= r;
-      cosx /= r;
-    }
   public:
 
     /**
diff --git a/include/GeographicLib/Config.h b/include/GeographicLib/Config.h
index 1831e6d..8e23e71 100644
--- a/include/GeographicLib/Config.h
+++ b/include/GeographicLib/Config.h
@@ -1,8 +1,8 @@
 // This will be overwritten by ./configure
 
-#define GEOGRAPHICLIB_VERSION_STRING "1.41"
+#define GEOGRAPHICLIB_VERSION_STRING "1.42"
 #define GEOGRAPHICLIB_VERSION_MAJOR 1
-#define GEOGRAPHICLIB_VERSION_MINOR 41
+#define GEOGRAPHICLIB_VERSION_MINOR 42
 #define GEOGRAPHICLIB_VERSION_PATCH 0
 
 // Undefine HAVE_LONG_DOUBLE if this type is unknown to the compiler
diff --git a/include/GeographicLib/Constants.hpp b/include/GeographicLib/Constants.hpp
index 99671a3..1db512e 100644
--- a/include/GeographicLib/Constants.hpp
+++ b/include/GeographicLib/Constants.hpp
@@ -14,7 +14,9 @@
 
 /**
  * @relates GeographicLib::Constants
- * Pack the version components into a single integer.
+ * Pack the version components into a single integer.  Users should not rely on
+ * this particular packing of the components of the version number; see the
+ * documentation for GEOGRAPHICLIB_VERSION, below.
  **********************************************************************/
 #define GEOGRAPHICLIB_VERSION_NUM(a,b,c) ((((a) * 10000 + (b)) * 100) + (c))
 
@@ -22,7 +24,12 @@
  * @relates GeographicLib::Constants
  * The version of GeographicLib as a single integer, packed as MMmmmmpp where
  * MM is the major version, mmmm is the minor version, and pp is the patch
- * level.
+ * level.  Users should not rely on this particular packing of the components
+ * of the version number.  Instead they should use a test such as \code
+   #if GEOGRAPHICLIB_VERSION >= GEOGRAPHICLIB_VERSION_NUM(1,37,0)
+   ...
+   #endif
+ * \endcode
  **********************************************************************/
 #define GEOGRAPHICLIB_VERSION \
  GEOGRAPHICLIB_VERSION_NUM(GEOGRAPHICLIB_VERSION_MAJOR, \
@@ -31,11 +38,11 @@
 
 /**
  * @relates GeographicLib::Constants
- * A compile-time assert.  Use C++11 static_assert, if available.
+ * Is the C++11 static_assert available?
  **********************************************************************/
-#if !defined(GEOGRAPHICLIB_STATIC_ASSERT)
+#if !defined(GEOGRAPHICLIB_HAS_STATIC_ASSERT)
 #  if __cplusplus >= 201103 || defined(__GXX_EXPERIMENTAL_CXX0X__)
-#    define GEOGRAPHICLIB_STATIC_ASSERT static_assert
+#    define GEOGRAPHICLIB_HAS_STATIC_ASSERT 1
 #  elif defined(_MSC_VER) && _MSC_VER >= 1600
 // For reference, here is a table of Visual Studio and _MSC_VER
 // correspondences:
@@ -51,6 +58,18 @@
 //   1700     vc11  (2012)
 //   1800     vc12  (2013)
 //   1900     vc14  (2015)
+#    define GEOGRAPHICLIB_HAS_STATIC_ASSERT 1
+#  else
+#    define GEOGRAPHICLIB_HAS_STATIC_ASSERT 0
+#  endif
+#endif
+
+/**
+ * @relates GeographicLib::Constants
+ * A compile-time assert.  Use C++11 static_assert, if available.
+ **********************************************************************/
+#if !defined(GEOGRAPHICLIB_STATIC_ASSERT)
+#  if GEOGRAPHICLIB_HAS_STATIC_ASSERT
 #    define GEOGRAPHICLIB_STATIC_ASSERT static_assert
 #  else
 #    define GEOGRAPHICLIB_STATIC_ASSERT(cond,reason) \
diff --git a/include/GeographicLib/DMS.hpp b/include/GeographicLib/DMS.hpp
index 132072e..801421e 100644
--- a/include/GeographicLib/DMS.hpp
+++ b/include/GeographicLib/DMS.hpp
@@ -2,7 +2,7 @@
  * \file DMS.hpp
  * \brief Header for GeographicLib::DMS class
  *
- * Copyright (c) Charles Karney (2008-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2008-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  **********************************************************************/
@@ -32,26 +32,6 @@ namespace GeographicLib {
    * \include example-DMS.cpp
    **********************************************************************/
   class GEOGRAPHICLIB_EXPORT DMS {
-  private:
-    typedef Math::real real;
-    // Replace all occurrences of pat by c
-    static void replace(std::string& s, const std::string& pat, char c) {
-      std::string::size_type p = 0;
-      while (true) {
-        p = s.find(pat, p);
-        if (p == std::string::npos)
-          break;
-        s.replace(p, pat.length(), 1, c);
-      }
-    }
-    static const std::string hemispheres_;
-    static const std::string signs_;
-    static const std::string digits_;
-    static const std::string dmsindicators_;
-    static const std::string components_[3];
-    static Math::real NumMatch(const std::string& s);
-    DMS();                      // Disable constructor
-
   public:
 
     /**
@@ -108,6 +88,29 @@ namespace GeographicLib {
       SECOND = 2,
     };
 
+  private:
+    typedef Math::real real;
+    // Replace all occurrences of pat by c
+    static void replace(std::string& s, const std::string& pat, char c) {
+      std::string::size_type p = 0;
+      while (true) {
+        p = s.find(pat, p);
+        if (p == std::string::npos)
+          break;
+        s.replace(p, pat.length(), 1, c);
+      }
+    }
+    static const std::string hemispheres_;
+    static const std::string signs_;
+    static const std::string digits_;
+    static const std::string dmsindicators_;
+    static const std::string components_[3];
+    static Math::real NumMatch(const std::string& s);
+    static Math::real InternalDecode(const std::string& dmsa, flag& ind);
+    DMS();                      // Disable constructor
+
+  public:
+
     /**
      * Convert a string in DMS to an angle.
      *
@@ -130,14 +133,14 @@ namespace GeographicLib {
      * (colon) may be used to <i>separate</i> these components (numbers must
      * appear before and after each colon); thus 50d30'10.3" may be
      * written as 50:30:10.3, 5.5' may be written 0:5.5, and so on.  The
-     * integer parts of the minutes and seconds components must be less than
-     * 60.  A single leading sign is permitted.  A hemisphere designator (N, E,
-     * W, S) may be added to the beginning or end of the string.  The result is
-     * multiplied by the implied sign of the hemisphere designator (negative
-     * for S and W).  In addition \e ind is set to DMS::LATITUDE if N or S is
-     * present, to DMS::LONGITUDE if E or W is present, and to DMS::NONE
-     * otherwise.  Throws an error on a malformed string.  No check is
-     * performed on the range of the result.  Examples of legal and illegal
+     * integer parts of the minutes and seconds components must be less
+     * than 60.  A single leading sign is permitted.  A hemisphere designator
+     * (N, E, W, S) may be added to the beginning or end of the string.  The
+     * result is multiplied by the implied sign of the hemisphere designator
+     * (negative for S and W).  In addition \e ind is set to DMS::LATITUDE if N
+     * or S is present, to DMS::LONGITUDE if E or W is present, and to
+     * DMS::NONE otherwise.  Throws an error on a malformed string.  No check
+     * is performed on the range of the result.  Examples of legal and illegal
      * strings are
      * - <i>LEGAL</i> (all the entries on each line are equivalent)
      *   - -20.51125, 20d30'40.5"S, -20°30'40.5, -20d30.675,
@@ -148,6 +151,20 @@ namespace GeographicLib {
      *   - 4d5"4', 4::5, 4:5:, :4:5, 4d4.5'4", -N20.5, 1.8e2d, 4:60,
      *     4d-5'
      *
+     * The decoding operation can also perform a single addition or subtraction
+     * operation.  If the string includes an <i>internal</i> sign (i.e., not at
+     * the beginning nor immediately after an initial hemisphere designator),
+     * then the string is split immediately before that sign and each half is
+     * decoded according to the above rules and the results added.  The second
+     * half can include a hemisphere designator, but it must come at the end (a
+     * hemisphere designator is not allowed after the initial sign).  If both
+     * halves include hemisphere designators then these must compatible; e.g.,
+     * you cannot mix N and E.  Examples of legal and illegal combinations are
+     * - <i>LEGAL</i> (these are all equivalent)
+     *   - 070:00:45, 70:01:15W+0:0.5, 70:01:15W-0:0:30W, W70:01:15+0:0:30E
+     * - <i>ILLEGAL</i> (the exception thrown explains the problem)
+     *   - 70:01:15W+0:0:15N, W70:01:15+W0:0:15
+     *
      * <b>NOTE:</b> At present, all the string handling in the C++
      * implementation %GeographicLib is with 8-bit characters.  The support for
      * unicode symbols for degrees, minutes, and seconds is therefore via the
@@ -156,7 +173,7 @@ namespace GeographicLib {
      * course.)
      *
      * Here is the list of Unicode symbols supported for degrees, minutes,
-     * seconds:
+     * seconds, and the sign:
      * - degrees:
      *   - d, D lower and upper case letters
      *   - U+00b0 degree symbol (°)
@@ -173,6 +190,8 @@ namespace GeographicLib {
      *   - U+2033 double prime (″)
      *   - U+201d right double quote (”)
      *   - ' ' any two consecutive symbols for minutes
+     * - leading sign:
+     *   - U+2212 minus sign (−)
      * .
      * The codes with a leading zero byte, e.g., U+00b0, are accepted in their
      * UTF-8 coded form 0xc2 0xb0 and as a single byte 0xb0.
diff --git a/include/GeographicLib/Ellipsoid.hpp b/include/GeographicLib/Ellipsoid.hpp
index 5b2e644..3e103c0 100644
--- a/include/GeographicLib/Ellipsoid.hpp
+++ b/include/GeographicLib/Ellipsoid.hpp
@@ -2,7 +2,7 @@
  * \file Ellipsoid.hpp
  * \brief Header for GeographicLib::Ellipsoid class
  *
- * Copyright (c) Charles Karney (2012-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2012-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  **********************************************************************/
@@ -41,20 +41,10 @@ namespace GeographicLib {
     typedef Math::real real;
     static const int numit_ = 10;
     real stol_;
-    real _a, _f, _f1, _f12, _e2, _e, _e12, _n, _b;
+    real _a, _f, _f1, _f12, _e2, _es, _e12, _n, _b;
     TransverseMercator _tm;
     EllipticFunction _ell;
     AlbersEqualArea _au;
-    static inline real tand(real x) {
-      using std::abs; using std::tan;
-      return
-        abs(x) == real(90) ? (x < 0 ?
-                              - TransverseMercator::overflow()
-                              : TransverseMercator::overflow()) :
-        tan(x * Math::degree());
-    }
-    static inline real atand(real x)
-    { using std::atan; return atan(x) / Math::degree(); }
 
     // These are the alpha and beta coefficients in the Krueger series from
     // TransverseMercator.  Thy are used by RhumbSolve to compute
diff --git a/include/GeographicLib/GeoCoords.hpp b/include/GeographicLib/GeoCoords.hpp
index d25a6ff..70106cc 100644
--- a/include/GeographicLib/GeoCoords.hpp
+++ b/include/GeographicLib/GeoCoords.hpp
@@ -133,7 +133,8 @@ namespace GeographicLib {
      * seconds, etc.  Use d, ', and " to mark off the degrees,
      * minutes and seconds.  Various alternative symbols for degrees, minutes,
      * and seconds are allowed.  Alternatively, use : to separate these
-     * components.  (See DMS::Decode for details.)  Thus
+     * components.  A single addition or subtraction is allowed.  (See
+     * DMS::Decode for details.)  Thus
      * - 40d30'30"
      * - 40d30'30
      * - 40°30'30
@@ -142,12 +143,16 @@ namespace GeographicLib {
      * - 40:30:30
      * - 40:30.5
      * - 40.508333333
+     * - 40:30+0:0:30
+     * - 40:31-0:0.5
      * .
-     * all specify the same angle.  The leading sign applies to all components
-     * so -1d30 is -(1+30/60) = -1.5.  Latitudes must be in the range
-     * [−90°, 90°] and longitudes in the range
-     * [−540°, 540°).  Internally longitudes are reduced
-     * to the range [−180°, 180°).
+     * all specify the same angle.  The leading sign applies to the following
+     * components so -1d30 is -(1+30/60) = −1.5.  However, note
+     * that -1:30-0:0:15 is parsed as (-1:30) + (-0:0:15) = −(1+30/60)
+     * − (15/3600).  Latitudes must be in the range [−90°,
+     * 90°] and longitudes in the range [−540°, 540°).
+     * Internally longitudes are reduced to the range [−180°,
+     * 180°).
      *
      * <b>UTM/UPS parsing</b>: For UTM zones (−80° ≤ Lat <
      * 84°), the zone designator is made up of a zone number (for 1 to 60)
diff --git a/include/GeographicLib/Geodesic.hpp b/include/GeographicLib/Geodesic.hpp
index 4c73fa6..2a297b9 100644
--- a/include/GeographicLib/Geodesic.hpp
+++ b/include/GeographicLib/Geodesic.hpp
@@ -2,7 +2,7 @@
  * \file Geodesic.hpp
  * \brief Header for GeographicLib::Geodesic class
  *
- * Copyright (c) Charles Karney (2009-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2009-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  **********************************************************************/
@@ -202,24 +202,6 @@ namespace GeographicLib {
 
     static real SinCosSeries(bool sinp,
                              real sinx, real cosx, const real c[], int n);
-    static inline real AngRound(real x) {
-      // The makes the smallest gap in x = 1/16 - nextafter(1/16, 0) = 1/2^57
-      // for reals = 0.7 pm on the earth if x is an angle in degrees.  (This
-      // is about 1000 times more resolution than we get with angles around 90
-      // degrees.)  We use this to avoid having to deal with near singular
-      // cases when x is non-zero but tiny (e.g., 1.0e-200).
-      using std::abs;
-      const real z = 1/real(16);
-      GEOGRAPHICLIB_VOLATILE real y = abs(x);
-      // The compiler mustn't "simplify" z - (z - y) to y
-      y = y < z ? z - (z - y) : y;
-      return x < 0 ? -y : y;
-    }
-    static inline void SinCosNorm(real& sinx, real& cosx) {
-      real r = Math::hypot(sinx, cosx);
-      sinx /= r;
-      cosx /= r;
-    }
     static real Astroid(real x, real y);
 
     real _a, _f, _f1, _e2, _ep2, _n, _b, _c2, _etol2;
diff --git a/include/GeographicLib/GeodesicExact.hpp b/include/GeographicLib/GeodesicExact.hpp
index 80573e4..472ce1d 100644
--- a/include/GeographicLib/GeodesicExact.hpp
+++ b/include/GeographicLib/GeodesicExact.hpp
@@ -2,7 +2,7 @@
  * \file GeodesicExact.hpp
  * \brief Header for GeographicLib::GeodesicExact class
  *
- * Copyright (c) Charles Karney (2012-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2012-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  **********************************************************************/
@@ -101,24 +101,6 @@ namespace GeographicLib {
     };
 
     static real CosSeries(real sinx, real cosx, const real c[], int n);
-    static inline real AngRound(real x) {
-      // The makes the smallest gap in x = 1/16 - nextafter(1/16, 0) = 1/2^57
-      // for reals = 0.7 pm on the earth if x is an angle in degrees.  (This
-      // is about 1000 times more resolution than we get with angles around 90
-      // degrees.)  We use this to avoid having to deal with near singular
-      // cases when x is non-zero but tiny (e.g., 1.0e-200).
-      using std::abs;
-      const real z = 1/real(16);
-      GEOGRAPHICLIB_VOLATILE real y = abs(x);
-      // The compiler mustn't "simplify" z - (z - y) to y
-      y = y < z ? z - (z - y) : y;
-      return x < 0 ? -y : y;
-    }
-    static inline void SinCosNorm(real& sinx, real& cosx) {
-      real r = Math::hypot(sinx, cosx);
-      sinx /= r;
-      cosx /= r;
-    }
     static real Astroid(real x, real y);
 
     real _a, _f, _f1, _e2, _ep2, _n, _b, _c2, _etol2;
diff --git a/include/GeographicLib/Geoid.hpp b/include/GeographicLib/Geoid.hpp
index b4b4255..87c4807 100644
--- a/include/GeographicLib/Geoid.hpp
+++ b/include/GeographicLib/Geoid.hpp
@@ -2,7 +2,7 @@
  * \file Geoid.hpp
  * \brief Header for GeographicLib::Geoid class
  *
- * Copyright (c) Charles Karney (2009-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2009-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  **********************************************************************/
@@ -68,7 +68,8 @@ namespace GeographicLib {
    * heights.  As a result of the way that the geoid data is stored, the
    * calculation of gradients can result in large quantization errors.  This is
    * particularly acute for fine grids, at high latitudes, and for the easterly
-   * gradient.
+   * gradient.  For this reason, the use of this facility is <b>DEPRECATED</b>.
+   * Instead, use the GravityModel class to evaluate the gravity vector.
    *
    * This class is typically \e not thread safe in that a single instantiation
    * cannot be safely used by multiple threads because of the way the object
@@ -309,13 +310,14 @@ namespace GeographicLib {
      *   never happens if (\e lat, \e lon) is within a successfully cached area.
      * @return geoid height (meters).
      *
-     * The latitude should be in [−90°, 90°] and
-     * longitude should be in [−540°, 540°).  As a result
-     * of the way that the geoid data is stored, the calculation of gradients
-     * can result in large quantization errors.  This is particularly acute for
-     * fine grids, at high latitudes, and for the easterly gradient.  If you
-     * need to compute the direction of the acceleration due to gravity
-     * accurately, you should use GravityModel::Gravity.
+     * The latitude should be in [−90°, 90°] and longitude should
+     * be in [−540°, 540°).  As a result of the way that the
+     * geoid data is stored, the calculation of gradients can result in large
+     * quantization errors.  This is particularly acute for fine grids, at high
+     * latitudes, and for the easterly gradient.  For this reason, the
+     * computation of the gradient is <b>DEPRECATED</b>.  If you need to
+     * compute the direction of the acceleration due to gravity accurately, you
+     * should use GravityModel::Gravity.
      **********************************************************************/
     Math::real operator()(real lat, real lon, real& gradn, real& grade) const {
       return height(lat, lon, true, gradn, grade);
diff --git a/include/GeographicLib/LambertConformalConic.hpp b/include/GeographicLib/LambertConformalConic.hpp
index e8cfc19..6cbc4e9 100644
--- a/include/GeographicLib/LambertConformalConic.hpp
+++ b/include/GeographicLib/LambertConformalConic.hpp
@@ -2,7 +2,7 @@
  * \file LambertConformalConic.hpp
  * \brief Header for GeographicLib::LambertConformalConic class
  *
- * Copyright (c) Charles Karney (2010-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2010-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  **********************************************************************/
@@ -57,18 +57,12 @@ namespace GeographicLib {
   class GEOGRAPHICLIB_EXPORT LambertConformalConic {
   private:
     typedef Math::real real;
-    real eps_, epsx_, tol_, ahypover_;
-    real _a, _f, _fm, _e2, _e, _e2m;
+    real eps_, epsx_, ahypover_;
+    real _a, _f, _fm, _e2, _es;
     real _sign, _n, _nc, _t0nm1, _scale, _lat0, _k0;
     real _scbet0, _tchi0, _scchi0, _psi0, _nrho0, _drhomax;
     static const int numit_ = 5;
     static inline real hyp(real x) { return Math::hypot(real(1), x); }
-    // e * atanh(e * x) = log( ((1 + e*x)/(1 - e*x))^(e/2) ) if f >= 0
-    // - sqrt(-e2) * atan( sqrt(-e2) * x)                    if f < 0
-    inline real eatanhe(real x) const {
-      using std::atan;
-      return _f >= 0 ? _e * Math::atanh(_e * x) : - _e * atan(_e * x);
-    }
     // Divided differences
     // Definition: Df(x,y) = (f(x)-f(y))/(x-y)
     // See:
@@ -132,7 +126,7 @@ namespace GeographicLib {
     // Deatanhe(x,y) = eatanhe((x-y)/(1-e^2*x*y))/(x-y)
     inline real Deatanhe(real x, real y) const {
       real t = x - y, d = 1 - _e2 * x * y;
-      return t ? eatanhe(t / d) / t : _e2 / d;
+      return t ? Math::eatanhe(t / d, _es) / t : _e2 / d;
     }
     void Init(real sphi1, real cphi1, real sphi2, real cphi2, real k1);
   public:
diff --git a/include/GeographicLib/MGRS.hpp b/include/GeographicLib/MGRS.hpp
index 23cf076..936eb48 100644
--- a/include/GeographicLib/MGRS.hpp
+++ b/include/GeographicLib/MGRS.hpp
@@ -203,7 +203,7 @@ namespace GeographicLib {
      * in the northern hemisphere and in [800 km, 3200 km] in the southern
      * hemisphere.
      *
-     * The ranges are 100 km more restrictive that for the conversion between
+     * The ranges are 100 km more restrictive than for the conversion between
      * geographic coordinates and UTM and UPS given by UTMUPS.  These
      * restrictions are dictated by the allowed letters in MGRS coordinates.
      * The choice of 9500 km for the maximum northing for northern hemisphere
diff --git a/include/GeographicLib/Math.hpp b/include/GeographicLib/Math.hpp
index 90afb92..22a82fc 100644
--- a/include/GeographicLib/Math.hpp
+++ b/include/GeographicLib/Math.hpp
@@ -2,7 +2,7 @@
  * \file Math.hpp
  * \brief Header for GeographicLib::Math class
  *
- * Copyright (c) Charles Karney (2008-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2008-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  **********************************************************************/
@@ -62,13 +62,13 @@
 #include <limits>
 
 #if GEOGRAPHICLIB_PRECISION == 4
+#include <boost/version.hpp>
+#if BOOST_VERSION >= 105600
+#include <boost/cstdfloat.hpp>
+#endif
 #include <boost/multiprecision/float128.hpp>
-#include <boost/math/special_functions/hypot.hpp>
-#include <boost/math/special_functions/expm1.hpp>
-#include <boost/math/special_functions/log1p.hpp>
-#include <boost/math/special_functions/atanh.hpp>
-#include <boost/math/special_functions/asinh.hpp>
-#include <boost/math/special_functions/cbrt.hpp>
+#include <boost/math/special_functions.hpp>
+__float128 fmaq(__float128, __float128, __float128);
 #elif GEOGRAPHICLIB_PRECISION == 5
 #include <mpreal.h>
 #endif
@@ -365,6 +365,34 @@ namespace GeographicLib {
     }
 
     /**
+     * Fused multiply and add.
+     *
+     * @tparam T the type of the arguments and the returned value.
+     * @param[in] x
+     * @param[in] y
+     * @param[in] z
+     * @return <i>xy</i> + <i>z</i>, correctly rounded (on those platforms with
+     *   support for the fma instruction).
+     **********************************************************************/
+    template<typename T> static inline T fma(T x, T y, T z) {
+#if GEOGRAPHICLIB_CXX11_MATH
+      using std::fma; return fma(x, y, z);
+#else
+      return x * y + z;
+#endif
+    }
+
+    /**
+     * Normalize a two-vector.
+     *
+     * @tparam T the type of the argument and the returned value.
+     * @param[in,out] x on output set to <i>x</i>/hypot(<i>x</i>, <i>y</i>).
+     * @param[in,out] y on output set to <i>y</i>/hypot(<i>x</i>, <i>y</i>).
+     **********************************************************************/
+    template<typename T> static inline void norm(T& x, T& y)
+    { T h = hypot(x, y); x /= h; y /= h; }
+
+    /**
      * The error-free sum of two numbers.
      *
      * @tparam T the type of the argument and the returned value.
@@ -437,6 +465,128 @@ namespace GeographicLib {
     }
 
     /**
+     * Coarsen a value close to zero.
+     *
+     * @tparam T the type of the argument and returned value.
+     * @param[in] x
+     * @return the coarsened value.
+     *
+     * The makes the smallest gap in \e x = 1/16 - nextafter(1/16, 0) =
+     * 1/2<sup>57</sup> for reals = 0.7 pm on the earth if \e x is an angle in
+     * degrees.  (This is about 1000 times more resolution than we get with
+     * angles around 90°.)  We use this to avoid having to deal with near
+     * singular cases when \e x is non-zero but tiny (e.g.,
+     * 10<sup>−200</sup>).
+     **********************************************************************/
+    template<typename T> static inline T AngRound(T x) {
+      using std::abs;
+      const T z = 1/T(16);
+      GEOGRAPHICLIB_VOLATILE T y = abs(x);
+      // The compiler mustn't "simplify" z - (z - y) to y
+      y = y < z ? z - (z - y) : y;
+      return x < 0 ? -y : y;
+    }
+
+    /**
+     * Evaluate the tangent function with the argument in degrees
+     *
+     * @tparam T the type of the argument and the returned value.
+     * @param[in] x in degrees.
+     * @return tan(<i>x</i>).
+     *
+     * If \e x = ±90°, then a suitably large (but finite) value is
+     * returned.
+     **********************************************************************/
+    template<typename T> static inline T tand(T x) {
+      using std::abs; using std::tan;
+      static const T overflow = 1 / Math::sq(std::numeric_limits<T>::epsilon());
+      return abs(x) != 90 ? tan(x * Math::degree()) :
+        (x < 0 ? -overflow : overflow);
+    }
+
+    /**
+     * Evaluate the atan function with the result in degrees
+     *
+     * @tparam T the type of the argument and the returned value.
+     * @param[in] x
+     * @return atan(<i>x</i>) in degrees.
+     *
+     * Large values for the argument return ±90°
+     **********************************************************************/
+    template<typename T> static inline T atand(T x) {
+      using std::abs; using std::atan;
+      static const T
+        overflow = 1 / (Math::sq(std::numeric_limits<T>::epsilon()) * 100);
+      return !(abs(x) >= overflow) ? atan(x) / Math::degree() :
+        (x > 0 ? 90 : -90);
+    }
+
+    /**
+     * Evaluate the atan2 function with the result in degrees
+     *
+     * @tparam T the type of the arguments and the returned value.
+     * @param[in] y
+     * @param[in] x
+     * @return atan2(<i>y</i>, <i>x</i>) in degrees.
+     *
+     * The result is in the range [−180° 180°).
+     **********************************************************************/
+    template<typename T> static inline T atan2d(T y, T x) {
+      using std::atan2;
+      return 0 - atan2(-y, x) / Math::degree();
+    }
+
+    /**
+     * Evaluate <i>e</i> atanh(<i>e x</i>)
+     *
+     * @tparam T the type of the argument and the returned value.
+     * @param[in] x
+     * @param[in] es the signed eccentricity =  sign(<i>e</i><sup>2</sup>)
+     *    sqrt(|<i>e</i><sup>2</sup>|)
+     * @return <i>e</i> atanh(<i>e x</i>)
+     *
+     * If <i>e</i><sup>2</sup> is negative (<i>e</i> is imaginary), the
+     * expression is evaluated in terms of atan.
+     **********************************************************************/
+    template<typename T> static T eatanhe(T x, T es);
+
+    /**
+     * tanχ in terms of tanφ
+     *
+     * @tparam T the type of the argument and the returned value.
+     * @param[in] tau τ = tanφ
+     * @param[in] es the signed eccentricity = sign(<i>e</i><sup>2</sup>)
+     *   sqrt(|<i>e</i><sup>2</sup>|)
+     * @return τ′ = tanχ
+     *
+     * See Eqs. (7--9) of
+     * C. F. F. Karney,
+     * <a href="https://dx.doi.org/10.1007/s00190-011-0445-3">
+     * Transverse Mercator with an accuracy of a few nanometers,</a>
+     * J. Geodesy 85(8), 475--485 (Aug. 2011)
+     * (preprint <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a>).
+     **********************************************************************/
+    template<typename T> static T taupf(T tau, T es);
+
+    /**
+     * tanφ in terms of tanχ
+     *
+     * @tparam T the type of the argument and the returned value.
+     * @param[in] taup τ′ = tanχ
+     * @param[in] es the signed eccentricity = sign(<i>e</i><sup>2</sup>)
+     *   sqrt(|<i>e</i><sup>2</sup>|)
+     * @return τ = tanφ
+     *
+     * See Eqs. (19--21) of
+     * C. F. F. Karney,
+     * <a href="https://dx.doi.org/10.1007/s00190-011-0445-3">
+     * Transverse Mercator with an accuracy of a few nanometers,</a>
+     * J. Geodesy 85(8), 475--485 (Aug. 2011)
+     * (preprint <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a>).
+     **********************************************************************/
+    template<typename T> static T tauf(T taup, T es);
+
+    /**
      * Test for finiteness.
      *
      * @tparam T the type of the argument.
@@ -547,6 +697,9 @@ namespace GeographicLib {
     static inline real cbrt(real x)
     { return boost::math::cbrt(x, boost_special_functions_policy()); }
 
+    static inline real fma(real x, real y, real z)
+    { return fmaq(__float128(x), __float128(y), __float128(z)); }
+
     static inline bool isnan(real x) { return boost::math::isnan(x); }
 
     static inline bool isfinite(real x) { return boost::math::isfinite(x); }
diff --git a/include/GeographicLib/PolarStereographic.hpp b/include/GeographicLib/PolarStereographic.hpp
index f25dd17..56afae0 100644
--- a/include/GeographicLib/PolarStereographic.hpp
+++ b/include/GeographicLib/PolarStereographic.hpp
@@ -2,7 +2,7 @@
  * \file PolarStereographic.hpp
  * \brief Header for GeographicLib::PolarStereographic class
  *
- * Copyright (c) Charles Karney (2008-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2008-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  **********************************************************************/
@@ -32,32 +32,8 @@ namespace GeographicLib {
   class GEOGRAPHICLIB_EXPORT PolarStereographic {
   private:
     typedef Math::real real;
-    real tol_;
-    // _Cx used to be _C but g++ 3.4 has a macro of that name
-    real _a, _f, _e2, _e, _e2m, _Cx, _c;
+    real _a, _f, _e2, _es, _e2m, _c;
     real _k0;
-    static const int numit_ = 5;
-    static inline real overflow() {
-    // Overflow value s.t. atan(overflow_) = pi/2
-      static const real
-        overflow = 1 / Math::sq(std::numeric_limits<real>::epsilon());
-      return overflow;
-    }
-    // tan(x) for x in [-pi/2, pi/2] ensuring that the sign is right
-    static inline real tanx(real x) {
-      using std::tan;
-      real t = tan(x);
-      // Write the tests this way to ensure that tanx(NaN()) is NaN()
-      return x >= 0 ?
-        (!(t <  0) ? t :  overflow()) :
-        (!(t >= 0) ? t : -overflow());
-    }
-    // Return e * atanh(e * x) for f >= 0, else return
-    // - sqrt(-e2) * atan( sqrt(-e2) * x) for f < 0
-    inline real eatanhe(real x) const {
-      using std::atan;
-      return _f >= 0 ? _e * Math::atanh(_e * x) : - _e * atan(_e * x);
-    }
   public:
 
     /**
diff --git a/include/GeographicLib/Rhumb.hpp b/include/GeographicLib/Rhumb.hpp
index d4ffce8..24718e7 100644
--- a/include/GeographicLib/Rhumb.hpp
+++ b/include/GeographicLib/Rhumb.hpp
@@ -75,20 +75,6 @@ namespace GeographicLib {
     static const int maxpow_ = GEOGRAPHICLIB_RHUMBAREA_ORDER;
     // _R[0] unused
     real _R[maxpow_ + 1];
-    static inline real overflow() {
-      // Overflow value s.t. atan(overflow_) = pi/2
-      static const real
-        overflow = 1 / Math::sq(std::numeric_limits<real>::epsilon());
-      return overflow;
-    }
-    static inline real tano(real x) {
-      using std::abs; using std::tan;
-      // Need the volatile declaration for optimized builds on 32-bit centos
-      // with g++ 4.4.7
-      GEOGRAPHICLIB_VOLATILE real y = 2 * abs(x);
-      return
-        y == Math::pi() ? (x < 0 ? - overflow() : overflow()) : tan(x);
-    }
     static inline real gd(real x)
     { using std::atan; using std::sinh; return atan(sinh(x)); }
 
@@ -107,9 +93,12 @@ namespace GeographicLib {
       real t = x - y;
       return t ? 2 * Math::atanh(t / (x + y)) / t : 1 / x;
     }
+    // N.B., x and y are in degrees
     static inline real Dtan(real x, real y) {
-      real d = x - y, tx = tano(x), ty = tano(y), txy = tx * ty;
-      return d ? (2 * txy > -1 ? (1 + txy) * tano(d) : tx - ty) / d :
+      real d = x - y, tx = Math::tand(x), ty = Math::tand(y), txy = tx * ty;
+      return d ?
+        (2 * txy > -1 ? (1 + txy) * Math::tand(d) : tx - ty) /
+        (d * Math::degree()) :
         1 + txy;
     }
     static inline real Datan(real x, real y) {
@@ -144,22 +133,14 @@ namespace GeographicLib {
       using std::sinh;
       return Datan(sinh(x), sinh(y)) * Dsinh(x, y);
     }
-    static inline real Dgdinv(real x, real y) {
-      return Dasinh(tano(x), tano(y)) * Dtan(x, y);
-    }
-    // Copied from LambertConformalConic...
-    // e * atanh(e * x) = log( ((1 + e*x)/(1 - e*x))^(e/2) ) if f >= 0
-    // - sqrt(-e2) * atan( sqrt(-e2) * x)                    if f < 0
-    inline real eatanhe(real x) const {
-      using std::atan;
-      return _ell._f >= 0 ? _ell._e * Math::atanh(_ell._e * x) :
-        - _ell._e * atan(_ell._e * x);
-    }
+    // N.B., x and y are the tangents of the angles
+    static inline real Dgdinv(real x, real y)
+    { return Dasinh(x, y) / Datan(x, y); }
     // Copied from LambertConformalConic...
     // Deatanhe(x,y) = eatanhe((x-y)/(1-e^2*x*y))/(x-y)
     inline real Deatanhe(real x, real y) const {
       real t = x - y, d = 1 - _ell._e2 * x * y;
-      return t ? eatanhe(t / d) / t : _ell._e2 / d;
+      return t ? Math::eatanhe(t / d, _ell._es) / t : _ell._e2 / d;
     }
     // (E(x) - E(y)) / (x - y) -- E = incomplete elliptic integral of 2nd kind
     real DE(real x, real y) const;
@@ -177,6 +158,7 @@ namespace GeographicLib {
     real DRectifyingToConformal(real mux, real muy) const;
 
     // (mux - muy) / (psix - psiy)
+    // N.B., psix and psiy are in degrees
     real DIsometricToRectifying(real psix, real psiy) const;
     // (psix - psiy) / (mux - muy)
     real DRectifyingToIsometric(real mux, real muy) const;
diff --git a/include/GeographicLib/TransverseMercator.hpp b/include/GeographicLib/TransverseMercator.hpp
index 414e5a2..52032d2 100644
--- a/include/GeographicLib/TransverseMercator.hpp
+++ b/include/GeographicLib/TransverseMercator.hpp
@@ -2,7 +2,7 @@
  * \file TransverseMercator.hpp
  * \brief Header for GeographicLib::TransverseMercator class
  *
- * Copyright (c) Charles Karney (2008-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2008-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  **********************************************************************/
@@ -82,34 +82,9 @@ namespace GeographicLib {
     typedef Math::real real;
     static const int maxpow_ = GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER;
     static const int numit_ = 5;
-    real tol_;
-    real _a, _f, _k0, _e2, _e, _e2m,  _c, _n;
+    real _a, _f, _k0, _e2, _es, _e2m,  _c, _n;
     // _alp[0] and _bet[0] unused
     real _a1, _b1, _alp[maxpow_ + 1], _bet[maxpow_ + 1];
-    static inline real overflow() {
-      // Overflow value s.t. atan(overflow_) = pi/2
-      static const real
-        overflow = 1 / Math::sq(std::numeric_limits<real>::epsilon());
-      return overflow;
-    }
-    // tan(x) for x in [-pi/2, pi/2] ensuring that the sign is right
-    static inline real tanx(real x) {
-      using std::tan;
-      real t = tan(x);
-      // Write the tests this way to ensure that tanx(NaN()) is NaN()
-      return x >= 0 ?
-        (!(t <  0) ? t :  overflow()) :
-        (!(t >= 0) ? t : -overflow());
-    }
-    // Return e * atanh(e * x) for f >= 0, else return
-    // - sqrt(-e2) * atan( sqrt(-e2) * x) for f < 0
-    inline real eatanhe(real x) const {
-      using std::atan;
-      return _f >= 0 ? _e * Math::atanh(_e * x) : - _e * atan(_e * x);
-    }
-    real taupf(real tau) const;
-    real tauf(real taup) const;
-
     friend class Ellipsoid;           // For access to taupf, tauf.
   public:
 
diff --git a/include/GeographicLib/TransverseMercatorExact.hpp b/include/GeographicLib/TransverseMercatorExact.hpp
index 103af98..66f16bf 100644
--- a/include/GeographicLib/TransverseMercatorExact.hpp
+++ b/include/GeographicLib/TransverseMercatorExact.hpp
@@ -2,7 +2,7 @@
  * \file TransverseMercatorExact.hpp
  * \brief Header for GeographicLib::TransverseMercatorExact class
  *
- * Copyright (c) Charles Karney (2008-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2008-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  **********************************************************************/
@@ -85,23 +85,11 @@ namespace GeographicLib {
     bool _extendp;
     EllipticFunction _Eu, _Ev;
     static inline real overflow() {
-    // Overflow value s.t. atan(overflow_) = pi/2
+      // Overflow value s.t. atan(overflow_) = pi/2
       static const real
         overflow = 1 / Math::sq(std::numeric_limits<real>::epsilon());
       return overflow;
     }
-    // tan(x) for x in [-pi/2, pi/2] ensuring that the sign is right
-    static inline real tanx(real x) {
-      using std::tan;
-      real t = tan(x);
-      // Write the tests this way to ensure that tanx(NaN()) is NaN()
-      return x >= 0 ?
-        (!(t <  0) ? t :  overflow()) :
-        (!(t >= 0) ? t : -overflow());
-    }
-
-    real taup(real tau) const;
-    real taupinv(real taup) const;
 
     void zeta(real u, real snu, real cnu, real dnu,
               real v, real snv, real cnv, real dnv,
diff --git a/include/GeographicLib/UTMUPS.hpp b/include/GeographicLib/UTMUPS.hpp
index aa53621..a643abf 100644
--- a/include/GeographicLib/UTMUPS.hpp
+++ b/include/GeographicLib/UTMUPS.hpp
@@ -251,7 +251,7 @@ namespace GeographicLib {
      * [900km, 19600km] for the "southern" hemisphere.
      *
      * UPS eastings and northings are allowed to be in the range [1200km,
-     * 2800km] in the northern hemisphere and in [700km, 3100km] in the
+     * 2800km] in the northern hemisphere and in [700km, 3300km] in the
      * southern hemisphere.
      *
      * These ranges are 100km larger than allowed for the conversions to MGRS.
diff --git a/include/GeographicLib/Utility.hpp b/include/GeographicLib/Utility.hpp
index 1f0eabe..69feaee 100644
--- a/include/GeographicLib/Utility.hpp
+++ b/include/GeographicLib/Utility.hpp
@@ -296,6 +296,19 @@ namespace GeographicLib {
         return x < 0 ? std::string("-inf") :
           (x > 0 ? std::string("inf") : std::string("nan"));
       std::ostringstream s;
+#if GEOGRAPHICLIB_PRECISION == 4
+      // boost-quadmath treats precision == 0 as "use as many digits as
+      // necessary", so...
+      using std::floor;
+      if (p == 0) {
+        long long ix = (long long)(floor(x + Math::real(0.5)));
+        // Implement the "round ties to even" rule
+        if (Math::real(ix) == x + Math::real(0.5) && (ix % 2) == 1)
+          --ix;
+        s << ix;
+        return s.str();
+      }
+#endif
       if (p >= 0) s << std::fixed << std::setprecision(p);
       s << x; return s.str();
     }
@@ -416,7 +429,7 @@ namespace GeographicLib {
           std::numeric_limits<ExtT>::is_integer)
         {
           // Data is compatible (aside from the issue of endian-ness).
-          str.read(reinterpret_cast<char *>(array), num * sizeof(ExtT));
+          str.read(reinterpret_cast<char*>(array), num * sizeof(ExtT));
           if (!str.good())
             throw GeographicErr("Failure reading data");
           if (bigendp != Math::bigendian) { // endian mismatch -> swap bytes
@@ -433,7 +446,7 @@ namespace GeographicLib {
           int i = 0;                // index into output array
           while (k) {
             int n = (std::min)(k, bufsize);
-            str.read(reinterpret_cast<char *>(buffer), n * sizeof(ExtT));
+            str.read(reinterpret_cast<char*>(buffer), n * sizeof(ExtT));
             if (!str.good())
               throw GeographicErr("Failure reading data");
             for (int j = 0; j < n; ++j)
@@ -488,7 +501,7 @@ namespace GeographicLib {
           bigendp == Math::bigendian)
         {
           // Data is compatible (including endian-ness).
-          str.write(reinterpret_cast<const char *>(array), num * sizeof(ExtT));
+          str.write(reinterpret_cast<const char*>(array), num * sizeof(ExtT));
           if (!str.good())
             throw GeographicErr("Failure writing data");
         }
@@ -505,7 +518,7 @@ namespace GeographicLib {
               // cast to ExtT and fix endian-ness
               buffer[j] = bigendp == Math::bigendian ? ExtT(array[i++]) :
                 Math::swab<ExtT>(ExtT(array[i++]));
-            str.write(reinterpret_cast<const char *>(buffer), n * sizeof(ExtT));
+            str.write(reinterpret_cast<const char*>(buffer), n * sizeof(ExtT));
             if (!str.good())
               throw GeographicErr("Failure writing data");
             k -= n;
diff --git a/include/Makefile.in b/include/Makefile.in
index 66b25ce..98839f3 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994-2013 Free Software Foundation, Inc.
diff --git a/include/Makefile.mk b/include/Makefile.mk
index f45e8a7..6355a8a 100644
--- a/include/Makefile.mk
+++ b/include/Makefile.mk
@@ -1,4 +1,5 @@
-MODULES = AlbersEqualArea \
+MODULES = Accumulator \
+	AlbersEqualArea \
 	AzimuthalEquidistant \
 	CassiniSoldner \
 	CircularEngine \
@@ -21,6 +22,7 @@ MODULES = AlbersEqualArea \
 	MGRS \
 	MagneticCircle \
 	MagneticModel \
+	Math \
 	NormalGravity \
 	OSGB \
 	PolarStereographic \
@@ -31,9 +33,7 @@ MODULES = AlbersEqualArea \
 	TransverseMercatorExact \
 	UTMUPS \
 	Utility
-EXTRAHEADERS = Accumulator \
-	Constants \
-	Math \
+EXTRAHEADERS = Constants \
 	SphericalHarmonic \
 	SphericalHarmonic1 \
 	SphericalHarmonic2
diff --git a/java/direct/pom.xml b/java/direct/pom.xml
index 4f25d69..ae6d6de 100644
--- a/java/direct/pom.xml
+++ b/java/direct/pom.xml
@@ -9,7 +9,7 @@
   <groupId>net.sf.geographiclib.example</groupId>
   <artifactId>Direct</artifactId>
   <name>Direct</name>
-  <version>1.40</version>
+  <version>1.42</version>
 
   <packaging>jar</packaging>
 
@@ -27,8 +27,8 @@
   <dependencies>
     <dependency>
       <groupId>net.sf.geographiclib</groupId>
-      <artifactId>GeographicLib</artifactId>
-      <version>1.40</version>
+      <artifactId>GeographicLib-Java</artifactId>
+      <version>1.42</version>
     </dependency>
   </dependencies>
 
diff --git a/java/inverse/pom.xml b/java/inverse/pom.xml
index 02fe630..c2ce244 100644
--- a/java/inverse/pom.xml
+++ b/java/inverse/pom.xml
@@ -9,7 +9,7 @@
   <groupId>net.sf.geographiclib.example</groupId>
   <artifactId>Inverse</artifactId>
   <name>Inverse</name>
-  <version>1.40</version>
+  <version>1.42</version>
 
   <packaging>jar</packaging>
 
@@ -27,8 +27,8 @@
   <dependencies>
     <dependency>
       <groupId>net.sf.geographiclib</groupId>
-      <artifactId>GeographicLib</artifactId>
-      <version>1.40</version>
+      <artifactId>GeographicLib-Java</artifactId>
+      <version>1.42</version>
     </dependency>
   </dependencies>
 
diff --git a/java/planimeter/pom.xml b/java/planimeter/pom.xml
index f8d5c81..91222b7 100644
--- a/java/planimeter/pom.xml
+++ b/java/planimeter/pom.xml
@@ -9,7 +9,7 @@
   <groupId>net.sf.geographiclib.example</groupId>
   <artifactId>Planimeter</artifactId>
   <name>Planimeter</name>
-  <version>1.40</version>
+  <version>1.42</version>
 
   <packaging>jar</packaging>
 
@@ -27,8 +27,8 @@
   <dependencies>
     <dependency>
       <groupId>net.sf.geographiclib</groupId>
-      <artifactId>GeographicLib</artifactId>
-      <version>1.40</version>
+      <artifactId>GeographicLib-Java</artifactId>
+      <version>1.42</version>
     </dependency>
   </dependencies>
 
diff --git a/java/pom.xml b/java/pom.xml
index e5d4607..4225825 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -7,18 +7,37 @@
   <modelVersion>4.0.0</modelVersion>
 
   <groupId>net.sf.geographiclib</groupId>
-  <artifactId>GeographicLib</artifactId>
-  <name>GeographicLib</name>
-  <version>1.40</version>
+  <artifactId>GeographicLib-Java</artifactId>
+  <version>1.42</version>
 
   <packaging>jar</packaging>
 
+  <licenses>
+    <license>
+      <name>The MIT License(MIT)</name>
+      <url>http://opensource.org/licenses/MIT</url>
+    </license>
+  </licenses>
+
+  <name>Java implementation of GeographicLib</name>
   <description>
     This is a Java implementation of the geodesic algorithms from
     GeographicLib. This is a self-contained library which makes it
     easy to do geodesic computations for an ellipsoid of revolution in
     a Java program. It requires Java version 1.1 or later.
   </description>
+  <url>http://geographiclib.sf.net</url>
+
+  <developers>
+    <developer>
+      <name>Charles Karney</name>
+      <email>charles at karney.com</email>
+      <organization></organization>
+      <organizationUrl>
+        http://sourceforge.net/u/karney/profile/
+      </organizationUrl>
+    </developer>
+  </developers>
 
   <properties>
     <basedir>.</basedir>
@@ -31,9 +50,6 @@
     <maven-site.version>3.0</maven-site.version>
   </properties>
 
-  <dependencies>
-  </dependencies>
-
   <build>
     <plugins>
       <plugin>
@@ -55,40 +71,99 @@
         </configuration>
       </plugin>
 
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-javadoc-plugin</artifactId>
-        <version>${maven-javadoc.version}</version>
-        <configuration>
-          <show>public</show>
-          <nohelp>true</nohelp>
-        </configuration>
-        <executions>
-          <execution>
-            <id>attach-javadocs</id>
-            <goals>
-              <goal>jar</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
     </plugins>
-
   </build>
 
+  <profiles>
+    <profile>
+      <id>release</id>
+      <build>
+        <plugins>
+
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-javadoc-plugin</artifactId>
+            <version>${maven-javadoc.version}</version>
+            <configuration>
+              <show>public</show>
+              <nohelp>true</nohelp>
+            </configuration>
+            <executions>
+              <execution>
+                <id>attach-javadocs</id>
+                <goals>
+                  <goal>jar</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-source-plugin</artifactId>
+            <version>2.2.1</version>
+            <executions>
+              <execution>
+                <id>attach-sources</id>
+                <goals>
+                  <goal>jar-no-fork</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+
+          <plugin>
+            <groupId>org.sonatype.plugins</groupId>
+            <artifactId>nexus-staging-maven-plugin</artifactId>
+            <version>1.6.3</version>
+            <extensions>true</extensions>
+            <configuration>
+              <serverId>ossrh</serverId>
+              <nexusUrl>https://oss.sonatype.org/</nexusUrl>
+              <autoReleaseAfterClose>true</autoReleaseAfterClose>
+            </configuration>
+          </plugin>
+
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-gpg-plugin</artifactId>
+            <version>1.5</version>
+            <executions>
+              <execution>
+                <id>sign-artifacts</id>
+                <phase>verify</phase>
+                <goals>
+                  <goal>sign</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+
   <distributionManagement>
+    <snapshotRepository>
+      <id>ossrh</id>
+      <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+    </snapshotRepository>
+    <repository>
+      <id>ossrh</id>
+      <url>https://oss.sonatype.org/service/local/staging/deploy/maven2</url>
+    </repository>
   </distributionManagement>
 
   <scm>
     <connection>
-      scm:git:http://
+      scm:git://git.code.sf.net/p/geographiclib/code
     </connection>
     <developerConnection>
-      scm:git:https://
+      scm:git:http://git.code.sf.net/p/geographiclib/code
     </developerConnection>
-    <tag>devel</tag>
     <url>
-      http://
+      http://sourceforge.net/p/geographiclib/code/ci/master/tree/
     </url>
   </scm>
 
diff --git a/java/src/main/java/net/sf/geographiclib/Geodesic.java b/java/src/main/java/net/sf/geographiclib/Geodesic.java
index ca4518c..6b16651 100644
--- a/java/src/main/java/net/sf/geographiclib/Geodesic.java
+++ b/java/src/main/java/net/sf/geographiclib/Geodesic.java
@@ -169,11 +169,8 @@ package net.sf.geographiclib;
  * <li>C. F. F. Karney,
  *   <a href="https://dx.doi.org/10.1007/s00190-012-0578-z">
  *   Algorithms for geodesics</a>,
- *   J. Geodesy <b>87</b>, 43–55 (2013);
- *   DOI: <a href="https://dx.doi.org/10.1007/s00190-012-0578-z">
- *   10.1007/s00190-012-0578-z</a>;
- *   addenda: <a href="http://geographiclib.sf.net/geod-addenda.html">
- *   geod-addenda.html</a>.
+ *   J. Geodesy <b>87</b>, 43–55 (2013)
+ *   (<a href="http://geographiclib.sf.net/geod-addenda.html">addenda</a>).
  * </ul>
  * <p>
  * Example of use:
diff --git a/java/src/main/java/net/sf/geographiclib/GeodesicLine.java b/java/src/main/java/net/sf/geographiclib/GeodesicLine.java
index 80a32b8..6bcc23f 100644
--- a/java/src/main/java/net/sf/geographiclib/GeodesicLine.java
+++ b/java/src/main/java/net/sf/geographiclib/GeodesicLine.java
@@ -31,11 +31,8 @@ package net.sf.geographiclib;
  *   C. F. F. Karney,
  *   <a href="https://dx.doi.org/10.1007/s00190-012-0578-z">
  *   Algorithms for geodesics</a>,
- *   J. Geodesy <b>87</b>, 43–55 (2013);
- *   DOI: <a href="https://dx.doi.org/10.1007/s00190-012-0578-z">
- *   10.1007/s00190-012-0578-z</a>;
- *   addenda: <a href="http://geographiclib.sf.net/geod-addenda.html">
- *   geod-addenda.html</a>.
+ *   J. Geodesy <b>87</b>, 43–55 (2013)
+ *   (<a href="http://geographiclib.sf.net/geod-addenda.html">addenda</a>).
  * </ul>
  * <p>
  * Here's an example of using this class
diff --git a/java/src/main/java/net/sf/geographiclib/PolygonArea.java b/java/src/main/java/net/sf/geographiclib/PolygonArea.java
index 1edd979..018035b 100644
--- a/java/src/main/java/net/sf/geographiclib/PolygonArea.java
+++ b/java/src/main/java/net/sf/geographiclib/PolygonArea.java
@@ -17,11 +17,8 @@ package net.sf.geographiclib;
  *   C. F. F. Karney,
  *   <a href="https://dx.doi.org/10.1007/s00190-012-0578-z">
  *   Algorithms for geodesics</a>,
- *   J. Geodesy <b>87</b>, 43–55 (2013);
- *   DOI: <a href="https://dx.doi.org/10.1007/s00190-012-0578-z">
- *   10.1007/s00190-012-0578-z</a>;
- *   addenda: <a href="http://geographiclib.sf.net/geod-addenda.html">
- *   geod-addenda.html</a>.
+ *   J. Geodesy <b>87</b>, 43–55 (2013)
+ *   (<a href="http://geographiclib.sf.net/geod-addenda.html">addenda</a>).
  * </ul>
  * <p>
  * This class lets you add vertices one at a time to the polygon.  The area
diff --git a/java/src/main/java/net/sf/geographiclib/package-info.java b/java/src/main/java/net/sf/geographiclib/package-info.java
index e593097..a36ebf9 100644
--- a/java/src/main/java/net/sf/geographiclib/package-info.java
+++ b/java/src/main/java/net/sf/geographiclib/package-info.java
@@ -1,37 +1,52 @@
 /**
  * <h1>Geodesic routines from GeographicLib implemented in Java</h1>
  * @author Charles F. F. Karney (charles at karney.com)
- * @version 1.40
+ * @version 1.42
  *
  * <h2>Abstract</h2>
  * <p>
- * This is a Java implementation of the geodesic algorithms from <a
- * href="http://geographiclib.sf.net">GeographicLib</a>.  This is a
- * self-contained library which makes it easy to do geodesic computations
- * for an ellipsoid of revolution in a Java program.  It requires Java
- * version 1.1 or later.
- * <p>
- * <h2>Downloading the source</h2>
+ * GeographicLib-Java is a Java implementation of the geodesic algorithms from
+ * <a href="http://geographiclib.sf.net">GeographicLib</a>.  This is a
+ * self-contained library which makes it easy to do geodesic computations for
+ * an ellipsoid of revolution in a Java program.  It requires Java version 1.1
+ * or later.
+ *
+ * <h2>Downloading</h2>
  * <p>
- * The Java library is part of GeographicLib which available for download at
+ * Download either the source or the pre-built package as follows:
+ *
+ * <h3>Obtaining the source</h3>
+ * GeographicLib-Java is part of GeographicLib which available for download at
  * <ul>
  * <li>
- *   <a href="https://sf.net/projects/geographiclib/files/distrib/GeographicLib-1.40.tar.gz">
- *   GeographicLib-1.40.tar.gz</a>
+ *   <a href="https://sf.net/projects/geographiclib/files/distrib/GeographicLib-1.42.tar.gz">
+ *   GeographicLib-1.42.tar.gz</a>
  * <li>
- *   <a href="https://sf.net/projects/geographiclib/files/distrib/GeographicLib-1.40.zip">
- *   GeographicLib-1.40.zip</a>
+ *   <a href="https://sf.net/projects/geographiclib/files/distrib/GeographicLib-1.42.zip">
+ *   GeographicLib-1.42.zip</a>
  * </ul>
  * <p>
  * as either a compressed tar file (tar.gz) or a zip file.  After unpacking
- * the source, the Java library can be found in GeographicLib-1.40/java.  (This
+ * the source, the Java library can be found in GeographicLib-1.42/java.  (This
  * library is completely independent from the rest of GeodegraphicLib.)  The
  * library consists of the files in the src/main/java/net/sf/geographiclib
  * subdirectory.
- * <p>
+ *
+ * <h3>The pre-built package</h3>
+ * GeographicLib-Java is available as a pre-built package on Maven Central
+ * (thanks to Chris Bennight for help on this deployment).  So, if you use
+ * <a href="http://maven.apache.org/">maven</a> to build your code, you just
+ * need to include the dependency <pre>{@code
+ *   <dependency>
+ *     <groupId>net.sf.geographiclib</groupId>
+ *     <artifactId>GeographicLib-Java</artifactId>
+ *     <version>1.42</version>
+ *   </dependency> }</pre>
+ * in your {@code pom.xml}.
+ *
  * <h2>Sample programs</h2>
  * <p>
- * Also included are 3 small test programs
+ * Included with the source are 3 small test programs
  * <ul>
  * <li>
  *    {@code direct/src/main/java/Direct.java} is a simple command line utility
@@ -40,13 +55,11 @@
  *    {@code inverse/src/main/java/Inverse.java} is a simple command line
  *    utility for solving the inverse geodesic problem;
  * <li>
- *    {@code planimter/src/main/java/Planimeter.java} is a simple command line
+ *    {@code planimeter/src/main/java/Planimeter.java} is a simple command line
  *    utility for computing the area of a geodesic polygon given its vertices.
  * </ul>
  * <p>
- * Here, for example, is {@code Inverse.java}
- * <pre>
- * {@code
+ * Here, for example, is {@code Inverse.java} <pre>{@code
  * // Solve the inverse geodesic problem.
  *
  * // This program reads in lines with lat1, lon1, lat2, lon2 and prints
@@ -69,17 +82,21 @@
  *     catch (Exception e) {}
  *   }
  * }}</pre>
+ *
  * <h2>Compiling and running a sample program</h2>
+ * <p>
  * Three difference ways of compiling and running {@code Inverse.java} are
  * given.  These differ in the degree to which they utilize
  * <a href="http://maven.apache.org/">maven</a> to manage your Java code and
  * its dependencies.  (Thanks to Skip Breidbach for supplying the maven
  * support.)
+ *
  * <h3>Without using maven</h3>
  * Compile and run as follows <pre>
  * cd inverse/src/main/java
  * javac -cp .:../../../../src/main/java Inverse.java
  * echo -30 0 29.5 179.5 | java -cp .:../../../../src/main/java Inverse </pre>
+ *
  * <h3>Using maven to package GeographicLib</h3>
  * Use <a href="http://maven.apache.org/">maven</a> to create a jar file by
  * running (in the main java directory) <pre>
@@ -88,19 +105,18 @@
  * some additional packages to your local repository.)  Then compile and run
  * Inverse.java with <pre>
  * cd inverse/src/main/java
- * javac -cp .:../../../../target/GeographicLib-1.40.jar Inverse.java
+ * javac -cp .:../../../../target/GeographicLib-1.42.jar Inverse.java
  * echo -30 0 29.5 179.5 |
- *   java -cp .:../../../../target/GeographicLib-1.40.jar Inverse </pre>
+ *   java -cp .:../../../../target/GeographicLib-1.42.jar Inverse </pre>
+ *
  * <h3>Using maven to build and run {@code Inverse.java}</h3>
- * Use <a href="http://maven.apache.org/">maven</a> to install GeographicLib by
- * running (in the main java directory) <pre>
- * mvn install </pre>
- * (Your first run of maven may take a long time, because it needs to download
- * some additional packages to your local repository.)  Then compile and run
- * Inverse.java using {@code inverse/pom.xml} with <pre>
+ * The sample code includes a {@code pom.xml} which downloads the pre-built
+ * artifact for GeographicLib-Java from Maven Central.  So you can compile and
+ * run Inverse.java with <pre>
  * cd inverse
  * mvn compile
  * echo -30 0 29.5 179.5 | mvn -q exec:java </pre>
+ *
  * <h2>Using the library</h2>
  * <p>
  * <ul>
@@ -139,12 +155,12 @@
  *   net.sf.geographiclib.PolygonResult}).
  * </ul>
  * <p>
- * The documentation is generated using javadoc when {@code mvn package} is run
- * (the top of the documentation tree is {@code target/apidocs/index.html}).
- * This is also available on the web at
- * <a href="http://geographiclib.sf.net/html/C/index.html">
- * http://geographiclib.sf.net/html/C/index.html</a>.
- * <p>
+ * The documentation is generated using javadoc when
+ * {@code mvn package -P release} is run (the top of the documentation tree is
+ * {@code target/apidocs/index.html}).  This is also available on the web at
+ * <a href="http://geographiclib.sf.net/html/java/index.html">
+ * http://geographiclib.sf.net/html/java/index.html</a>.
+ *
  * <h2>External links</h2>
  * <p>
  * <ul>
@@ -171,6 +187,9 @@
  *   <a href="http://geographiclib.sf.net/html/Fortran/index.html">The
  *   Fortran library</a>.
  * <li>
+ *   <a href="http://www.mathworks.com/matlabcentral/fileexchange/50605">
+ *    MATLAB toolbox</a>.
+ * <li>
  *   The section in the GeographicLib documentation on geodesics:
  *   <a href="http://geographiclib.sf.net/html/geodesic.html">Geodesics
  *   on an ellipsoid of revolution</a>.
diff --git a/legacy/C/geodesic.c b/legacy/C/geodesic.c
index fd0214c..dd88662 100644
--- a/legacy/C/geodesic.c
+++ b/legacy/C/geodesic.c
@@ -771,7 +771,7 @@ real geod_geninverse(const struct geod_geodesic* g,
       for (tripn = FALSE, tripb = FALSE; numit < maxit2; ++numit) {
         /* the WGS84 test set: mean = 1.47, sd = 1.25, max = 16
          * WGS84 and random input: mean = 2.85, sd = 0.60 */
-        real dv,
+        real dv = 0,
           v = (Lambda12(g, sbet1, cbet1, dn1, sbet2, cbet2, dn2, salp1, calp1,
                         &salp2, &calp2, &sig12, &ssig1, &csig1, &ssig2, &csig2,
                         &eps, &omg12, numit < maxit1, &dv, C1a, C2a, C3a)
diff --git a/legacy/C/geodesic.h b/legacy/C/geodesic.h
index 6b2afc5..2be5aec 100644
--- a/legacy/C/geodesic.h
+++ b/legacy/C/geodesic.h
@@ -113,7 +113,7 @@
  * http://geographiclib.sourceforge.net/
  *
  * This library was distributed with
- * <a href="../index.html">GeographicLib</a> 1.40.
+ * <a href="../index.html">GeographicLib</a> 1.42.
  **********************************************************************/
 
 #if !defined(GEODESIC_H)
@@ -128,13 +128,36 @@
  * The minor version of the geodesic library.  (This tracks the version of
  * GeographicLib.)
  **********************************************************************/
-#define GEODESIC_VERSION_MINOR 40
+#define GEODESIC_VERSION_MINOR 42
 /**
  * The patch level of the geodesic library.  (This tracks the version of
  * GeographicLib.)
  **********************************************************************/
 #define GEODESIC_VERSION_PATCH 0
 
+/**
+ * Pack the version components into a single integer.  Users should not rely on
+ * this particular packing of the components of the version number; see the
+ * documentation for GEODESIC_VERSION, below.
+ **********************************************************************/
+#define GEODESIC_VERSION_NUM(a,b,c) ((((a) * 10000 + (b)) * 100) + (c))
+
+/**
+ * The version of the geodesic library as a single integer, packed as MMmmmmpp
+ * where MM is the major version, mmmm is the minor version, and pp is the
+ * patch level.  Users should not rely on this particular packing of the
+ * components of the version number.  Instead they should use a test such as
+ * \code
+   #if GEODESIC_VERSION >= GEODESIC_VERSION_NUM(1,40,0)
+   ...
+   #endif
+ * \endcode
+ **********************************************************************/
+#define GEODESIC_VERSION \
+ GEODESIC_VERSION_NUM(GEODESIC_VERSION_MAJOR, \
+                      GEODESIC_VERSION_MINOR, \
+                      GEODESIC_VERSION_PATCH)
+
 #if defined(__cplusplus)
 extern "C" {
 #endif
diff --git a/legacy/Fortran/geoddirect.for b/legacy/Fortran/geoddirect.for
index 4cc9048..85c6e60 100644
--- a/legacy/Fortran/geoddirect.for
+++ b/legacy/Fortran/geoddirect.for
@@ -12,7 +12,7 @@
       include 'geodesic.inc'
 
       double precision a, f, lat1, lon1, azi1, lat2, lon2, azi2, s12,
-     +    dummy
+     +    dummy1, dummy2, dummy3, dummy4, dummy5
       integer flags, omask
 
 * WGS84 values
@@ -25,7 +25,8 @@
  10   continue
       read(*, *, end=90, err=90) lat1, lon1, azi1, s12
       call direct(a, f, lat1, lon1, azi1, s12, flags,
-     +    lat2, lon2, azi2, omask, dummy, dummy, dummy, dummy, dummy)
+     +    lat2, lon2, azi2, omask,
+     +    dummy1, dummy2, dummy3, dummy4, dummy5)
       print 20, lat2, lon2, azi2
  20   format(f20.15, 1x, f20.15, 1x, f20.15)
       go to 10
diff --git a/legacy/Fortran/geodesic.for b/legacy/Fortran/geodesic.for
index 4998a20..0c12324 100644
--- a/legacy/Fortran/geodesic.for
+++ b/legacy/Fortran/geodesic.for
@@ -117,7 +117,7 @@
 *! http://geographiclib.sourceforge.net/
 *!
 *! This library was distributed with
-*! <a href="../index.html">GeographicLib</a> 1.40.
+*! <a href="../index.html">GeographicLib</a> 1.42.
 
 *> Solve the direct geodesic problem
 *!
diff --git a/legacy/Fortran/geodinverse.for b/legacy/Fortran/geodinverse.for
index a9883b8..aa562c3 100644
--- a/legacy/Fortran/geodinverse.for
+++ b/legacy/Fortran/geodinverse.for
@@ -12,7 +12,7 @@
       include 'geodesic.inc'
 
       double precision a, f, lat1, lon1, azi1, lat2, lon2, azi2, s12,
-     +    dummy
+     +    dummy1, dummy2, dummy3, dummy4, dummy5
       integer omask
 
 * WGS84 values
@@ -24,7 +24,8 @@
  10   continue
       read(*, *, end=90, err=90) lat1, lon1, lat2, lon2
       call invers(a, f, lat1, lon1, lat2, lon2,
-     +    s12, azi1, azi2, omask, dummy, dummy, dummy, dummy, dummy)
+     +    s12, azi1, azi2, omask,
+     +    dummy1, dummy2, dummy3, dummy4 , dummy5)
       print 20, azi1, azi2, s12
  20   format(f20.15, 1x, f20.15, 1x, f19.10)
       go to 10
diff --git a/man/CartConvert.1 b/man/CartConvert.1
index 40ecef0..d1815e7 100644
--- a/man/CartConvert.1
+++ b/man/CartConvert.1
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.29)
+.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
 .\"
 .\" Standard preamble:
 .\" ========================================================================
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "CARTCONVERT 1"
-.TH CARTCONVERT 1 "2015-03-09" "GeographicLib 1.41" "GeographicLib Utilities"
+.TH CARTCONVERT 1 "2015-04-28" "GeographicLib 1.42" "GeographicLib Utilities"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff --git a/man/CartConvert.usage b/man/CartConvert.usage
index aebe039..6b2758d 100644
--- a/man/CartConvert.usage
+++ b/man/CartConvert.usage
@@ -9,7 +9,7 @@ int usage(int retval, bool brief) {
 "For full documentation type:\n"
 "    CartConvert --help\n"
 "or visit:\n"
-"    http://geographiclib.sf.net/1.41/CartConvert.1.html\n";
+"    http://geographiclib.sf.net/1.42/CartConvert.1.html\n";
   else
     ( retval ? std::cerr : std::cout ) << "Man page:\n"
 "NAME\n"
diff --git a/man/ConicProj.1 b/man/ConicProj.1
index cd75e14..15593fe 100644
--- a/man/ConicProj.1
+++ b/man/ConicProj.1
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.29)
+.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
 .\"
 .\" Standard preamble:
 .\" ========================================================================
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "CONICPROJ 1"
-.TH CONICPROJ 1 "2015-03-09" "GeographicLib 1.41" "GeographicLib Utilities"
+.TH CONICPROJ 1 "2015-04-28" "GeographicLib 1.42" "GeographicLib Utilities"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff --git a/man/ConicProj.usage b/man/ConicProj.usage
index e827916..8c0b2a7 100644
--- a/man/ConicProj.usage
+++ b/man/ConicProj.usage
@@ -9,7 +9,7 @@ int usage(int retval, bool brief) {
 "For full documentation type:\n"
 "    ConicProj --help\n"
 "or visit:\n"
-"    http://geographiclib.sf.net/1.41/ConicProj.1.html\n";
+"    http://geographiclib.sf.net/1.42/ConicProj.1.html\n";
   else
     ( retval ? std::cerr : std::cout ) << "Man page:\n"
 "NAME\n"
diff --git a/man/GeoConvert.1 b/man/GeoConvert.1
index 4b4efb6..9143c17 100644
--- a/man/GeoConvert.1
+++ b/man/GeoConvert.1
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.29)
+.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
 .\"
 .\" Standard preamble:
 .\" ========================================================================
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "GEOCONVERT 1"
-.TH GEOCONVERT 1 "2015-03-09" "GeographicLib 1.41" "GeographicLib Utilities"
+.TH GEOCONVERT 1 "2015-04-28" "GeographicLib 1.42" "GeographicLib Utilities"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -182,6 +182,13 @@ longitude.  For example, the following are all equivalent
 \&    44d24 33d18N
 \&    33:18 44:24
 .Ve
+.Sp
+It is also possible to carry out addition or subtraction operations in
+geographic coordinates.  For example the point 15" east of 39N 70W is
+.Sp
+.Vb 1
+\&    39N 70W+0:0:15E
+.Ve
 .IP "\fB\s-1UTM/UPS\s0\fR" 4
 .IX Item "UTM/UPS"
 3 tokens (output option \fB\-u\fR) given as \fIzone\fR+\fIhemisphere\fR \fIeasting\fR
@@ -420,6 +427,30 @@ file \f(CW\*(C`input.txt\*(C'\fR should just contain the plain coordinates.
 \&   echo 38SMB4488 | GeoConvert \-u      => 38n 444500 3688500
 \&   echo E44d24 N33d20 | GeoConvert \-m \-p \-3 => 38SMB4488
 .Ve
+.PP
+GeoConvert can be used to do simple arithmetic using degree, minutes,
+and seconds.  For example, sometimes data is tiled in 15 second squares
+tagged by the \s-1DMS\s0 representation of the \s-1SW\s0 corner.  The tags of the tile
+at 38:59:45N 077:02:00W and its 8 neighbors are then given by
+.PP
+.Vb 10
+\&    t=0:0:15
+\&    for y in \-$t +0 +$t; do
+\&        for x in \-$t +0 +$t; do
+\&            echo 38:59:45N$y 077:02:00W$x
+\&        done
+\&    done | GeoConvert \-: \-p \-1 | tr \-d \*(Aq: \*(Aq
+\&    =>
+\&    385930N0770215W
+\&    385930N0770200W
+\&    385930N0770145W
+\&    385945N0770215W
+\&    385945N0770200W
+\&    385945N0770145W
+\&    390000N0770215W
+\&    390000N0770200W
+\&    390000N0770145W
+.Ve
 .SH "ERRORS"
 .IX Header "ERRORS"
 An illegal line of input will print an error message to standard output
diff --git a/man/GeoConvert.1.html b/man/GeoConvert.1.html
index f0769ff..236a780 100644
--- a/man/GeoConvert.1.html
+++ b/man/GeoConvert.1.html
@@ -36,6 +36,10 @@
     44d24 33d18N
     33:18 44:24</code></pre>
 
+<p>It is also possible to carry out addition or subtraction operations in geographic coordinates. For example the point 15" east of 39N 70W is</p>
+
+<pre><code>    39N 70W+0:0:15E</code></pre>
+
 </dd>
 <dt id="UTM-UPS"><b>UTM/UPS</b></dt>
 <dd>
@@ -284,6 +288,25 @@
    echo 38SMB4488 | GeoConvert -u      => 38n 444500 3688500
    echo E44d24 N33d20 | GeoConvert -m -p -3 => 38SMB4488</code></pre>
 
+<p>GeoConvert can be used to do simple arithmetic using degree, minutes, and seconds. For example, sometimes data is tiled in 15 second squares tagged by the DMS representation of the SW corner. The tags of the tile at 38:59:45N 077:02:00W and its 8 neighbors are then given by</p>
+
+<pre><code>    t=0:0:15
+    for y in -$t +0 +$t; do
+        for x in -$t +0 +$t; do
+            echo 38:59:45N$y 077:02:00W$x
+        done
+    done | GeoConvert -: -p -1 | tr -d ': '
+    =>
+    385930N0770215W
+    385930N0770200W
+    385930N0770145W
+    385945N0770215W
+    385945N0770200W
+    385945N0770145W
+    390000N0770215W
+    390000N0770200W
+    390000N0770145W</code></pre>
+
 <h1 id="ERRORS">ERRORS</h1>
 
 <p>An illegal line of input will print an error message to standard output beginning with <code>ERROR:</code> and causes <b>GeoConvert</b> to return an exit code of 1. However, an error does not cause <b>GeoConvert</b> to terminate; following lines will be converted.</p>
diff --git a/man/GeoConvert.pod b/man/GeoConvert.pod
index 07d160e..5ab3004 100644
--- a/man/GeoConvert.pod
+++ b/man/GeoConvert.pod
@@ -47,6 +47,11 @@ longitude.  For example, the following are all equivalent
     44d24 33d18N
     33:18 44:24
 
+It is also possible to carry out addition or subtraction operations in
+geographic coordinates.  For example the point 15" east of 39N 70W is
+
+    39N 70W+0:0:15E
+
 =item B<UTM/UPS>
 
 3 tokens (output option B<-u>) given as I<zone>+I<hemisphere> I<easting>
@@ -303,6 +308,28 @@ file C<input.txt> should just contain the plain coordinates.
    echo 38SMB4488 | GeoConvert -u      => 38n 444500 3688500
    echo E44d24 N33d20 | GeoConvert -m -p -3 => 38SMB4488
 
+GeoConvert can be used to do simple arithmetic using degree, minutes,
+and seconds.  For example, sometimes data is tiled in 15 second squares
+tagged by the DMS representation of the SW corner.  The tags of the tile
+at 38:59:45N 077:02:00W and its 8 neighbors are then given by
+
+    t=0:0:15
+    for y in -$t +0 +$t; do
+        for x in -$t +0 +$t; do
+            echo 38:59:45N$y 077:02:00W$x
+        done
+    done | GeoConvert -: -p -1 | tr -d ': '
+    =>
+    385930N0770215W
+    385930N0770200W
+    385930N0770145W
+    385945N0770215W
+    385945N0770200W
+    385945N0770145W
+    390000N0770215W
+    390000N0770200W
+    390000N0770145W
+
 =head1 ERRORS
 
 An illegal line of input will print an error message to standard output
diff --git a/man/GeoConvert.usage b/man/GeoConvert.usage
index 71e7e00..c86577e 100644
--- a/man/GeoConvert.usage
+++ b/man/GeoConvert.usage
@@ -9,7 +9,7 @@ int usage(int retval, bool brief) {
 "For full documentation type:\n"
 "    GeoConvert --help\n"
 "or visit:\n"
-"    http://geographiclib.sf.net/1.41/GeoConvert.1.html\n";
+"    http://geographiclib.sf.net/1.42/GeoConvert.1.html\n";
   else
     ( retval ? std::cerr : std::cout ) << "Man page:\n"
 "NAME\n"
@@ -51,6 +51,12 @@ int usage(int retval, bool brief) {
 "               44d24 33d18N\n"
 "               33:18 44:24\n"
 "\n"
+"           It is also possible to carry out addition or subtraction operations\n"
+"           in geographic coordinates.  For example the point 15\" east of 39N\n"
+"           70W is\n"
+"\n"
+"               39N 70W+0:0:15E\n"
+"\n"
 "       UTM/UPS\n"
 "           3 tokens (output option -u) given as zone+hemisphere easting\n"
 "           northing or easting northing zone+hemisphere, where hemisphere is\n"
@@ -251,6 +257,28 @@ int usage(int retval, bool brief) {
 "          echo 38SMB4488 | GeoConvert -u      => 38n 444500 3688500\n"
 "          echo E44d24 N33d20 | GeoConvert -m -p -3 => 38SMB4488\n"
 "\n"
+"       GeoConvert can be used to do simple arithmetic using degree, minutes,\n"
+"       and seconds.  For example, sometimes data is tiled in 15 second squares\n"
+"       tagged by the DMS representation of the SW corner.  The tags of the\n"
+"       tile at 38:59:45N 077:02:00W and its 8 neighbors are then given by\n"
+"\n"
+"           t=0:0:15\n"
+"           for y in -$t +0 +$t; do\n"
+"               for x in -$t +0 +$t; do\n"
+"                   echo 38:59:45N$y 077:02:00W$x\n"
+"               done\n"
+"           done | GeoConvert -: -p -1 | tr -d ': '\n"
+"           =>\n"
+"           385930N0770215W\n"
+"           385930N0770200W\n"
+"           385930N0770145W\n"
+"           385945N0770215W\n"
+"           385945N0770200W\n"
+"           385945N0770145W\n"
+"           390000N0770215W\n"
+"           390000N0770200W\n"
+"           390000N0770145W\n"
+"\n"
 "ERRORS\n"
 "       An illegal line of input will print an error message to standard output\n"
 "       beginning with \"ERROR:\" and causes GeoConvert to return an exit code of\n"
diff --git a/man/GeodSolve.1 b/man/GeodSolve.1
index 0d75358..f9de88d 100644
--- a/man/GeodSolve.1
+++ b/man/GeodSolve.1
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.29)
+.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
 .\"
 .\" Standard preamble:
 .\" ========================================================================
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "GEODSOLVE 1"
-.TH GEODSOLVE 1 "2015-03-09" "GeographicLib 1.41" "GeographicLib Utilities"
+.TH GEODSOLVE 1 "2015-04-28" "GeographicLib 1.42" "GeographicLib Utilities"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff --git a/man/GeodSolve.usage b/man/GeodSolve.usage
index 8d841c5..1bb9dc1 100644
--- a/man/GeodSolve.usage
+++ b/man/GeodSolve.usage
@@ -9,7 +9,7 @@ int usage(int retval, bool brief) {
 "For full documentation type:\n"
 "    GeodSolve --help\n"
 "or visit:\n"
-"    http://geographiclib.sf.net/1.41/GeodSolve.1.html\n";
+"    http://geographiclib.sf.net/1.42/GeodSolve.1.html\n";
   else
     ( retval ? std::cerr : std::cout ) << "Man page:\n"
 "NAME\n"
diff --git a/man/GeodesicProj.1 b/man/GeodesicProj.1
index fae7901..f3ff4dd 100644
--- a/man/GeodesicProj.1
+++ b/man/GeodesicProj.1
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.29)
+.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
 .\"
 .\" Standard preamble:
 .\" ========================================================================
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "GEODESICPROJ 1"
-.TH GEODESICPROJ 1 "2015-03-09" "GeographicLib 1.41" "GeographicLib Utilities"
+.TH GEODESICPROJ 1 "2015-04-28" "GeographicLib 1.42" "GeographicLib Utilities"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff --git a/man/GeodesicProj.usage b/man/GeodesicProj.usage
index c2a337e..df12ab1 100644
--- a/man/GeodesicProj.usage
+++ b/man/GeodesicProj.usage
@@ -9,7 +9,7 @@ int usage(int retval, bool brief) {
 "For full documentation type:\n"
 "    GeodesicProj --help\n"
 "or visit:\n"
-"    http://geographiclib.sf.net/1.41/GeodesicProj.1.html\n";
+"    http://geographiclib.sf.net/1.42/GeodesicProj.1.html\n";
   else
     ( retval ? std::cerr : std::cout ) << "Man page:\n"
 "NAME\n"
diff --git a/man/GeoidEval.1 b/man/GeoidEval.1
index 590c50b..a38bb15 100644
--- a/man/GeoidEval.1
+++ b/man/GeoidEval.1
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.29)
+.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
 .\"
 .\" Standard preamble:
 .\" ========================================================================
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "GEOIDEVAL 1"
-.TH GEOIDEVAL 1 "2015-03-09" "GeographicLib 1.41" "GeographicLib Utilities"
+.TH GEOIDEVAL 1 "2015-04-28" "GeographicLib 1.42" "GeographicLib Utilities"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -202,7 +202,8 @@ the rate at which the geoid height changes per unit distance along the
 \&\s-1WGS84\s0 ellipsoid in the specified directions).  As a result of the way
 that the geoid data is stored, the calculation of gradients can result
 in large quantization errors.  This is particularly acute at high
-latitudes and for the easterly gradient.
+latitudes and for the easterly gradient.  For this reason, the use of
+this option is \fB\s-1DEPRECATED\s0\fR.
 .IP "\fB\-z\fR" 4
 .IX Item "-z"
 prefix each line of input by \fIzone\fR, e.g., \f(CW\*(C`38n\*(C'\fR.  This should be used
diff --git a/man/GeoidEval.1.html b/man/GeoidEval.1.html
index 3d419d3..36c5f9d 100644
--- a/man/GeoidEval.1.html
+++ b/man/GeoidEval.1.html
@@ -72,7 +72,7 @@
 <dt id="g"><b>-g</b></dt>
 <dd>
 
-<p>print the northerly and easterly gradients after the geoid height (i.e., the rate at which the geoid height changes per unit distance along the WGS84 ellipsoid in the specified directions). As a result of the way that the geoid data is stored, the calculation of gradients can result in large quantization errors. This is particularly acute at high latitudes and for the easterly gradient.</p>
+<p>print the northerly and easterly gradients after the geoid height (i.e., the rate at which the geoid height changes per unit distance along the WGS84 ellipsoid in the specified directions). As a result of the way that the geoid data is stored, the calculation of gradients can result in large quantization errors. This is particularly acute at high latitudes and for the easterly gradient. For this reason, the use of this option is <b>DEPRECATED</b>.</p>
 
 </dd>
 <dt id="z"><b>-z</b></dt>
diff --git a/man/GeoidEval.pod b/man/GeoidEval.pod
index b57a8ef..5aa3b30 100644
--- a/man/GeoidEval.pod
+++ b/man/GeoidEval.pod
@@ -75,7 +75,8 @@ the rate at which the geoid height changes per unit distance along the
 WGS84 ellipsoid in the specified directions).  As a result of the way
 that the geoid data is stored, the calculation of gradients can result
 in large quantization errors.  This is particularly acute at high
-latitudes and for the easterly gradient.
+latitudes and for the easterly gradient.  For this reason, the use of
+this option is B<DEPRECATED>.
 
 =item B<-z>
 
diff --git a/man/GeoidEval.usage b/man/GeoidEval.usage
index bd5e4b3..3273425 100644
--- a/man/GeoidEval.usage
+++ b/man/GeoidEval.usage
@@ -10,7 +10,7 @@ int usage(int retval, bool brief) {
 "For full documentation type:\n"
 "    GeoidEval --help\n"
 "or visit:\n"
-"    http://geographiclib.sf.net/1.41/GeoidEval.1.html\n";
+"    http://geographiclib.sf.net/1.42/GeoidEval.1.html\n";
   else
     ( retval ? std::cerr : std::cout ) << "Man page:\n"
 "NAME\n"
@@ -62,6 +62,7 @@ int usage(int retval, bool brief) {
 "           result of the way that the geoid data is stored, the calculation of\n"
 "           gradients can result in large quantization errors.  This is\n"
 "           particularly acute at high latitudes and for the easterly gradient.\n"
+"           For this reason, the use of this option is DEPRECATED.\n"
 "\n"
 "       -z  prefix each line of input by zone, e.g., \"38n\".  This should be\n"
 "           used when the input consists of UTM/UPS eastings and northings.\n"
diff --git a/man/Gravity.1 b/man/Gravity.1
index 50fa937..dcc245c 100644
--- a/man/Gravity.1
+++ b/man/Gravity.1
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.29)
+.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
 .\"
 .\" Standard preamble:
 .\" ========================================================================
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "GRAVITY 1"
-.TH GRAVITY 1 "2015-03-09" "GeographicLib 1.41" "GeographicLib Utilities"
+.TH GRAVITY 1 "2015-04-28" "GeographicLib 1.42" "GeographicLib Utilities"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff --git a/man/Gravity.usage b/man/Gravity.usage
index e2574b2..53cc8ca 100644
--- a/man/Gravity.usage
+++ b/man/Gravity.usage
@@ -9,7 +9,7 @@ int usage(int retval, bool brief) {
 "For full documentation type:\n"
 "    Gravity --help\n"
 "or visit:\n"
-"    http://geographiclib.sf.net/1.41/Gravity.1.html\n";
+"    http://geographiclib.sf.net/1.42/Gravity.1.html\n";
   else
     ( retval ? std::cerr : std::cout ) << "Man page:\n"
 "NAME\n"
diff --git a/man/MagneticField.1 b/man/MagneticField.1
index 4570b4c..0131039 100644
--- a/man/MagneticField.1
+++ b/man/MagneticField.1
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.29)
+.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
 .\"
 .\" Standard preamble:
 .\" ========================================================================
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "MAGNETICFIELD 1"
-.TH MAGNETICFIELD 1 "2015-03-09" "GeographicLib 1.41" "GeographicLib Utilities"
+.TH MAGNETICFIELD 1 "2015-04-28" "GeographicLib 1.42" "GeographicLib Utilities"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff --git a/man/MagneticField.usage b/man/MagneticField.usage
index e7b9bd1..212afcd 100644
--- a/man/MagneticField.usage
+++ b/man/MagneticField.usage
@@ -10,7 +10,7 @@ int usage(int retval, bool brief) {
 "For full documentation type:\n"
 "    MagneticField --help\n"
 "or visit:\n"
-"    http://geographiclib.sf.net/1.41/MagneticField.1.html\n";
+"    http://geographiclib.sf.net/1.42/MagneticField.1.html\n";
   else
     ( retval ? std::cerr : std::cout ) << "Man page:\n"
 "NAME\n"
diff --git a/man/Makefile.in b/man/Makefile.in
index eeb1ddc..3b8b8fc 100644
--- a/man/Makefile.in
+++ b/man/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994-2013 Free Software Foundation, Inc.
diff --git a/man/Planimeter.1 b/man/Planimeter.1
index d38bb09..9a997d0 100644
--- a/man/Planimeter.1
+++ b/man/Planimeter.1
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.29)
+.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
 .\"
 .\" Standard preamble:
 .\" ========================================================================
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "PLANIMETER 1"
-.TH PLANIMETER 1 "2015-03-09" "GeographicLib 1.41" "GeographicLib Utilities"
+.TH PLANIMETER 1 "2015-04-28" "GeographicLib 1.42" "GeographicLib Utilities"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff --git a/man/Planimeter.usage b/man/Planimeter.usage
index b562a86..0944934 100644
--- a/man/Planimeter.usage
+++ b/man/Planimeter.usage
@@ -9,7 +9,7 @@ int usage(int retval, bool brief) {
 "For full documentation type:\n"
 "    Planimeter --help\n"
 "or visit:\n"
-"    http://geographiclib.sf.net/1.41/Planimeter.1.html\n";
+"    http://geographiclib.sf.net/1.42/Planimeter.1.html\n";
   else
     ( retval ? std::cerr : std::cout ) << "Man page:\n"
 "NAME\n"
diff --git a/man/RhumbSolve.1 b/man/RhumbSolve.1
index 86c8c07..de1062b 100644
--- a/man/RhumbSolve.1
+++ b/man/RhumbSolve.1
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.29)
+.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
 .\"
 .\" Standard preamble:
 .\" ========================================================================
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "RHUMBSOLVE 1"
-.TH RHUMBSOLVE 1 "2015-03-09" "GeographicLib 1.41" "GeographicLib Utilities"
+.TH RHUMBSOLVE 1 "2015-04-28" "GeographicLib 1.42" "GeographicLib Utilities"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff --git a/man/RhumbSolve.usage b/man/RhumbSolve.usage
index 6238a99..45d63a2 100644
--- a/man/RhumbSolve.usage
+++ b/man/RhumbSolve.usage
@@ -9,7 +9,7 @@ int usage(int retval, bool brief) {
 "For full documentation type:\n"
 "    RhumbSolve --help\n"
 "or visit:\n"
-"    http://geographiclib.sf.net/1.41/RhumbSolve.1.html\n";
+"    http://geographiclib.sf.net/1.42/RhumbSolve.1.html\n";
   else
     ( retval ? std::cerr : std::cout ) << "Man page:\n"
 "NAME\n"
diff --git a/man/TransverseMercatorProj.1 b/man/TransverseMercatorProj.1
index 4568578..db8b28e 100644
--- a/man/TransverseMercatorProj.1
+++ b/man/TransverseMercatorProj.1
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.29)
+.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
 .\"
 .\" Standard preamble:
 .\" ========================================================================
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "TRANSVERSEMERCATORPROJ 1"
-.TH TRANSVERSEMERCATORPROJ 1 "2015-03-09" "GeographicLib 1.41" "GeographicLib Utilities"
+.TH TRANSVERSEMERCATORPROJ 1 "2015-04-28" "GeographicLib 1.42" "GeographicLib Utilities"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff --git a/man/TransverseMercatorProj.usage b/man/TransverseMercatorProj.usage
index 24207be..125d877 100644
--- a/man/TransverseMercatorProj.usage
+++ b/man/TransverseMercatorProj.usage
@@ -9,7 +9,7 @@ int usage(int retval, bool brief) {
 "For full documentation type:\n"
 "    TransverseMercatorProj --help\n"
 "or visit:\n"
-"    http://geographiclib.sf.net/1.41/TransverseMercatorProj.1.html\n";
+"    http://geographiclib.sf.net/1.42/TransverseMercatorProj.1.html\n";
   else
     ( retval ? std::cerr : std::cout ) << "Man page:\n"
 "NAME\n"
diff --git a/man/dummy.1.in b/man/dummy.1.in
index cc75044..8b6884d 100644
--- a/man/dummy.1.in
+++ b/man/dummy.1.in
@@ -1,12 +1,9 @@
-.IX Title "@TOOL@ 1"
 .TH @TOOL@ 1 "" "GeographicLib Utilities" "GeographicLib Utilities"
-.SH "NAME"
+.SH NAME
 @TOOL@ \-\- a GeographicLib utility
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fB at TOOL@\fR is part of GeographicLib, <http://geographiclib.sf.net>.
-For documentation, see
+.SH DESCRIPTION
+.B @TOOL@
+is part of GeographicLib, <http://geographiclib.sf.net>.  For
+documentation, see
 .PP
-.Vb 2
-\&   http://geographiclib.sf.net/@PROJECT_VERSION@/@TOOL@.1.html
-.Ve
+    http://geographiclib.sf.net/@PROJECT_VERSION@/@TOOL@.1.html
diff --git a/man/script.8.in b/man/script.8.in
index e31974b..201af1f 100644
--- a/man/script.8.in
+++ b/man/script.8.in
@@ -1,17 +1,15 @@
-.IX Title "@DATA@ 8"
-.TH @SCRIPT@ 8 "" "GeographicLib" "GeographicLib"
-.SH "NAME"
+.TH @SCRIPT@ 8 "" GeographicLib GeographicLib
+.SH NAME
 @SCRIPT@ \-\- a GeographicLib administrative tool
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-\&\fB at SCRIPT@\fR downloads and installs the @DATA@ datasets used by
-GeographicLib, <http://geographiclib.sf.net>.  For documentation, supply
-the \fB-h\fR option:
+.SH DESCRIPTION
+.B @SCRIPT@
+downloads and installs the @DATA@ datasets used by GeographicLib,
+<http://geographiclib.sf.net>.  For documentation, supply the
+.B -h
+option:
 .PP
-.Vb 2
-\&   @SCRIPT@ -h
-.Ve
+    @SCRIPT@ -h
 .PP
 By default, the datasets are installed in
-\&\f(CW\*(C`@GEOGRAPHICLIB_DATA@/@DATA@\*(C'\fR and
-the script requires write access to this directory.
+.I @GEOGRAPHICLIB_DATA@/@DATA@
+and the script requires write access to this directory.
diff --git a/matlab/CMakeLists.txt b/matlab/CMakeLists.txt
index 45cab20..cad60bc 100644
--- a/matlab/CMakeLists.txt
+++ b/matlab/CMakeLists.txt
@@ -1,92 +1,18 @@
-# Set up the matlab interface.  The .m files just contain the
-# documentation.  The .cpp files implement the interface.
-file (GLOB MATLAB_FILES [A-Za-z]*.m)
-file (GLOB MATLAB_INTERFACES [A-Za-z]*.cpp)
+# Install matlab files.
 if (COMMON_INSTALL_PATH)
-  set (INSTALL_MATLAB_DIR "libexec/GeographicLib/matlab")
+  # More Octave friendly would be "share/octave/site/m"
+  set (INSTALL_MATLAB_DIR "share/matlab")
 else ()
   set (INSTALL_MATLAB_DIR "matlab")
 endif ()
-# Both sets of files get installed
-install (FILES ${MATLAB_FILES} ${MATLAB_INTERFACES}
-  DESTINATION ${INSTALL_MATLAB_DIR})
+file (GLOB MATLAB_FILES geographiclib/[A-Za-z]*.m)
+install (FILES ${MATLAB_FILES} DESTINATION ${INSTALL_MATLAB_DIR}/geographiclib)
 # Install "private" functions
-file (GLOB PRIVATE_MATLAB_FILES private/[A-Za-z]*.m)
+file (GLOB PRIVATE_MATLAB_FILES geographiclib/private/[A-Za-z]*.m)
 install (FILES ${PRIVATE_MATLAB_FILES}
-  DESTINATION ${INSTALL_MATLAB_DIR}/private)
-
-# If MEX then compile the interface routines.  On non-Windows
-# systems, an attempt is made to minimize the number of addition target
-# generated.  For some reason this does not work with Windows systems.
-# On Windows systems, need also to copy the shared library to where the
-# mex files live (in the build and install trees).
-if (MEX)
-  if (MSVC)
-    set (CMAKE_INSTALL_DEBUG_LIBRARIES ON)
-    include (InstallRequiredSystemLibraries)
-    install (PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}
-      DESTINATION ${INSTALL_MATLAB_DIR})
-    add_custom_target (matlabinterface)
-    if (GEOGRAPHICLIB_SHARED_LIB)
-      set (_LIB Geographic-i)
-    else ()
-      set (_LIB Geographic)
-    endif ()
-  else ()
-    set (INTERFACE_LIST)
-    set (_LIB Geographic)
-  endif ()
-  foreach (INTERFACE ${MATLAB_INTERFACES})
-    get_filename_component (TARGET ${INTERFACE} NAME_WE)
-    set (TARGET_INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.${MEXEXT})
-    if (MSVC)
-      add_custom_target (matlab-${TARGET} DEPENDS ${TARGET_INTERFACE})
-      add_custom_command (OUTPUT ${TARGET_INTERFACE}
-        COMMAND
-          ${MEX} ${MEXOPTIONS} ${PROJECT_DEFINITIONS}
-            -I${PROJECT_BINARY_DIR}/include -I${PROJECT_SOURCE_DIR}/include
-            -L${PROJECT_BINARY_DIR}/lib/Release -l${_LIB}
-            ${INTERFACE}
-        COMMENT "Building matlab interface for ${TARGET}"
-        DEPENDS ${INTERFACE} ${PROJECT_LIBRARIES})
-      add_dependencies (matlabinterface matlab-${TARGET})
-      install (PROGRAMS ${TARGET_INTERFACE}
-        DESTINATION ${INSTALL_MATLAB_DIR} CONFIGURATIONS Release)
-      # Put all the matlab targets into a folder in the IDE
-      set_property (TARGET matlab-${TARGET} PROPERTY FOLDER matlab)
-    else ()
-      set (INTERFACE_LIST ${INTERFACE_LIST} ${TARGET_INTERFACE})
-      if (GEOGRAPHICLIB_SHARED_LIB)
-        set (RPATH_OPTS -Wl,-rpath=${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})
-      endif ()
-      add_custom_command (OUTPUT ${TARGET_INTERFACE}
-        COMMAND
-          ${MEX} ${MEXOPTIONS}
-            -I${PROJECT_BINARY_DIR}/include -I${PROJECT_SOURCE_DIR}/include
-            -L${PROJECT_BINARY_DIR}/src -l${_LIB}
-            ${RPATH_OPTS}
-            ${INTERFACE}
-        COMMENT "Building matlab interface for ${TARGET}"
-        DEPENDS ${INTERFACE} ${PROJECT_LIBRARIES})
-    endif ()
-  endforeach ()
-  if (NOT MSVC)
-    add_custom_target (matlabinterface DEPENDS ${INTERFACE_LIST})
-    install (PROGRAMS ${INTERFACE_LIST}
-      DESTINATION ${INSTALL_MATLAB_DIR} CONFIGURATIONS Release)
-  endif ()
-  if (MSVC AND GEOGRAPHICLIB_SHARED_LIB)
-    if (NOT CMAKE_VERSION VERSION_LESS 3.0)
-      # Suppress 3.0 warnings about use of the LOCATION target property
-      cmake_policy (SET CMP0026 OLD)
-    endif ()
-    get_target_property (_LOC ${PROJECT_LIBRARIES} LOCATION_RELEASE)
-    add_custom_command (TARGET matlabinterface POST_BUILD
-      COMMAND ${CMAKE_COMMAND} -E copy ${_LOC} ./)
-    get_filename_component (_NAME ${_LOC} NAME)
-    install (PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${_NAME}
-      DESTINATION ${INSTALL_MATLAB_DIR} CONFIGURATIONS Release)
-  endif ()
-
-  set_property (TARGET matlabinterface PROPERTY FOLDER matlab)
-endif ()
+  DESTINATION ${INSTALL_MATLAB_DIR}/geographiclib/private)
+# Install "legacy" functions
+file (GLOB LEGACY_FILES
+  geographiclib-legacy/[A-Za-z]*.m  geographiclib-legacy/[A-Za-z]*.cpp)
+install (FILES ${LEGACY_FILES}
+  DESTINATION ${INSTALL_MATLAB_DIR}/geographiclib-legacy)
diff --git a/matlab/Makefile.am b/matlab/Makefile.am
index 7e86512..02dbdef 100644
--- a/matlab/Makefile.am
+++ b/matlab/Makefile.am
@@ -3,97 +3,115 @@
 #
 # Copyright (C) 2011, Charles Karney <charles at karney.com>
 
-MATLAB_INTERFACE = \
-$(srcdir)/geodesicdirect.cpp \
-$(srcdir)/geodesicinverse.cpp \
-$(srcdir)/geodesicline.cpp \
-$(srcdir)/geoidheight.cpp \
-$(srcdir)/mgrsforward.cpp \
-$(srcdir)/mgrsreverse.cpp \
-$(srcdir)/utmupsforward.cpp \
-$(srcdir)/utmupsreverse.cpp \
-$(srcdir)/geocentricforward.cpp \
-$(srcdir)/geocentricreverse.cpp \
-$(srcdir)/localcartesianforward.cpp \
-$(srcdir)/localcartesianreverse.cpp \
-$(srcdir)/polygonarea.cpp
-
-MATLAB_DOC = \
-$(srcdir)/geodesicdirect.m \
-$(srcdir)/geodesicinverse.m \
-$(srcdir)/geodesicline.m \
-$(srcdir)/geoidheight.m \
-$(srcdir)/mgrsforward.m \
-$(srcdir)/mgrsreverse.m \
-$(srcdir)/utmupsforward.m \
-$(srcdir)/utmupsreverse.m \
-$(srcdir)/geocentricforward.m \
-$(srcdir)/geocentricreverse.m \
-$(srcdir)/localcartesianforward.m \
-$(srcdir)/localcartesianreverse.m \
-$(srcdir)/polygonarea.m
+MATLAB_FILES = \
+$(srcdir)/geographiclib/Contents.m \
+$(srcdir)/geographiclib/cassini_fwd.m \
+$(srcdir)/geographiclib/cassini_inv.m \
+$(srcdir)/geographiclib/defaultellipsoid.m \
+$(srcdir)/geographiclib/ecc2flat.m \
+$(srcdir)/geographiclib/eqdazim_fwd.m \
+$(srcdir)/geographiclib/eqdazim_inv.m \
+$(srcdir)/geographiclib/flat2ecc.m \
+$(srcdir)/geographiclib/gedistance.m \
+$(srcdir)/geographiclib/gedoc.m \
+$(srcdir)/geographiclib/geocent_fwd.m \
+$(srcdir)/geographiclib/geocent_inv.m \
+$(srcdir)/geographiclib/geodarea.m \
+$(srcdir)/geographiclib/geoddistance.m \
+$(srcdir)/geographiclib/geoddoc.m \
+$(srcdir)/geographiclib/geodreckon.m \
+$(srcdir)/geographiclib/geoid_height.m \
+$(srcdir)/geographiclib/geoid_load.m \
+$(srcdir)/geographiclib/gereckon.m \
+$(srcdir)/geographiclib/gnomonic_fwd.m \
+$(srcdir)/geographiclib/gnomonic_inv.m \
+$(srcdir)/geographiclib/loccart_fwd.m \
+$(srcdir)/geographiclib/loccart_inv.m \
+$(srcdir)/geographiclib/mgrs_fwd.m \
+$(srcdir)/geographiclib/mgrs_inv.m \
+$(srcdir)/geographiclib/polarst_fwd.m \
+$(srcdir)/geographiclib/polarst_inv.m \
+$(srcdir)/geographiclib/projdoc.m \
+$(srcdir)/geographiclib/tranmerc_fwd.m \
+$(srcdir)/geographiclib/tranmerc_inv.m \
+$(srcdir)/geographiclib/utmups_fwd.m \
+$(srcdir)/geographiclib/utmups_inv.m
 
-MATLAB_COMPILESCRIPT = $(srcdir)/geographiclibinterface.m
+MATLAB_PRIVATE = \
+$(srcdir)/geographiclib/private/A1m1f.m \
+$(srcdir)/geographiclib/private/A2m1f.m \
+$(srcdir)/geographiclib/private/A3coeff.m \
+$(srcdir)/geographiclib/private/A3f.m \
+$(srcdir)/geographiclib/private/AngDiff.m \
+$(srcdir)/geographiclib/private/AngNormalize.m \
+$(srcdir)/geographiclib/private/AngNormalize2.m \
+$(srcdir)/geographiclib/private/AngRound.m \
+$(srcdir)/geographiclib/private/C1f.m \
+$(srcdir)/geographiclib/private/C1pf.m \
+$(srcdir)/geographiclib/private/C2f.m \
+$(srcdir)/geographiclib/private/C3coeff.m \
+$(srcdir)/geographiclib/private/C3f.m \
+$(srcdir)/geographiclib/private/C4coeff.m \
+$(srcdir)/geographiclib/private/C4f.m \
+$(srcdir)/geographiclib/private/G4coeff.m \
+$(srcdir)/geographiclib/private/GeoRotation.m \
+$(srcdir)/geographiclib/private/SinCosSeries.m \
+$(srcdir)/geographiclib/private/cbrtx.m \
+$(srcdir)/geographiclib/private/cvmgt.m \
+$(srcdir)/geographiclib/private/eatanhe.m \
+$(srcdir)/geographiclib/private/geoid_file.m \
+$(srcdir)/geographiclib/private/geoid_load_file.m \
+$(srcdir)/geographiclib/private/norm2.m \
+$(srcdir)/geographiclib/private/sumx.m \
+$(srcdir)/geographiclib/private/swap.m \
+$(srcdir)/geographiclib/private/tauf.m \
+$(srcdir)/geographiclib/private/taupf.m
 
-MATLAB_GEOD = \
-$(srcdir)/geoddoc.m \
-$(srcdir)/geodreckon.m \
-$(srcdir)/geoddistance.m \
-$(srcdir)/geodarea.m \
-$(srcdir)/defaultellipsoid.m \
-$(srcdir)/ecc2flat.m \
-$(srcdir)/flat2ecc.m \
-$(srcdir)/geodproj.m \
-$(srcdir)/eqdazim_fwd.m \
-$(srcdir)/eqdazim_inv.m \
-$(srcdir)/cassini_fwd.m \
-$(srcdir)/cassini_inv.m \
-$(srcdir)/tranmerc_fwd.m \
-$(srcdir)/tranmerc_inv.m \
-$(srcdir)/gnomonic_fwd.m \
-$(srcdir)/gnomonic_inv.m \
-$(srcdir)/utm_fwd.m \
-$(srcdir)/utm_inv.m \
-$(srcdir)/gedoc.m \
-$(srcdir)/gereckon.m \
-$(srcdir)/gedistance.m
+MATLAB_LEGACY = \
+$(srcdir)/geographiclib-legacy/Contents.m \
+$(srcdir)/geographiclib-legacy/geocentricforward.m \
+$(srcdir)/geographiclib-legacy/geocentricreverse.m \
+$(srcdir)/geographiclib-legacy/geodesicdirect.m \
+$(srcdir)/geographiclib-legacy/geodesicinverse.m \
+$(srcdir)/geographiclib-legacy/geodesicline.m \
+$(srcdir)/geographiclib-legacy/geoidheight.m \
+$(srcdir)/geographiclib-legacy/localcartesianforward.m \
+$(srcdir)/geographiclib-legacy/localcartesianreverse.m \
+$(srcdir)/geographiclib-legacy/mgrsforward.m \
+$(srcdir)/geographiclib-legacy/mgrsreverse.m \
+$(srcdir)/geographiclib-legacy/polygonarea.m \
+$(srcdir)/geographiclib-legacy/utmupsforward.m \
+$(srcdir)/geographiclib-legacy/utmupsreverse.m
 
-MATLAB_GEOD_PRIVATE = \
-$(srcdir)/private/A1m1f.m \
-$(srcdir)/private/A2m1f.m \
-$(srcdir)/private/A3coeff.m \
-$(srcdir)/private/A3f.m \
-$(srcdir)/private/AngDiff.m \
-$(srcdir)/private/AngNormalize2.m \
-$(srcdir)/private/AngNormalize.m \
-$(srcdir)/private/AngRound.m \
-$(srcdir)/private/atanhee.m \
-$(srcdir)/private/C1f.m \
-$(srcdir)/private/C1pf.m \
-$(srcdir)/private/C2f.m \
-$(srcdir)/private/C3coeff.m \
-$(srcdir)/private/C3f.m \
-$(srcdir)/private/C4coeff.m \
-$(srcdir)/private/G4coeff.m \
-$(srcdir)/private/C4f.m \
-$(srcdir)/private/cbrt.m \
-$(srcdir)/private/cvmgt.m \
-$(srcdir)/private/SinCosNorm.m \
-$(srcdir)/private/SinCosSeries.m \
-$(srcdir)/private/sumx.m \
-$(srcdir)/private/swap.m
+MATLAB_INTERFACE = \
+$(srcdir)/geographiclib-legacy/geographiclibinterface.m \
+$(srcdir)/geographiclib-legacy/geocentricforward.cpp \
+$(srcdir)/geographiclib-legacy/geocentricreverse.cpp \
+$(srcdir)/geographiclib-legacy/geodesicdirect.cpp \
+$(srcdir)/geographiclib-legacy/geodesicinverse.cpp \
+$(srcdir)/geographiclib-legacy/geodesicline.cpp \
+$(srcdir)/geographiclib-legacy/geoidheight.cpp \
+$(srcdir)/geographiclib-legacy/localcartesianforward.cpp \
+$(srcdir)/geographiclib-legacy/localcartesianreverse.cpp \
+$(srcdir)/geographiclib-legacy/mgrsforward.cpp \
+$(srcdir)/geographiclib-legacy/mgrsreverse.cpp \
+$(srcdir)/geographiclib-legacy/polygonarea.cpp \
+$(srcdir)/geographiclib-legacy/utmupsforward.cpp \
+$(srcdir)/geographiclib-legacy/utmupsreverse.cpp
 
-MATLAB_ALL = $(MATLAB_INTERFACE) $(MATLAB_DOC) $(MATLAB_COMPILESCRIPT) \
-	$(MATLAB_GEOD)
+MATLAB_ALL = $(MATLAB_FILES) $(MATLAB_PRIVATE)
+MATLAB_LEGACY_ALL = $(MATLAB_LEGACY) $(MATLAB_INTERFACE)
 
-matlabdir=$(libexecdir)/GeographicLib/matlab
+matlabdir=$(DESTDIR)$(datadir)/matlab
 
 install:
-	$(INSTALL) -d $(DESTDIR)$(matlabdir)/private
-	$(INSTALL) -m 644 $(MATLAB_ALL) $(DESTDIR)$(matlabdir)
-	$(INSTALL) -m 644 $(MATLAB_GEOD_PRIVATE) $(DESTDIR)$(matlabdir)/private
+	$(INSTALL) -d $(matlabdir)/geographiclib/private
+	$(INSTALL) -d $(matlabdir)/geographiclib-legacy
+	$(INSTALL) -m 644 $(MATLAB_FILES) $(matlabdir)/geographiclib
+	$(INSTALL) -m 644 $(MATLAB_PRIVATE) $(matlabdir)/geographiclib/private
+	$(INSTALL) -m 644 $(MATLAB_LEGACY_ALL) $(matlabdir)/geographiclib-legacy
 
 clean-local:
 	rm -rf *.mex* *.oct
 
-EXTRA_DIST = Makefile.mk CMakeLists.txt $(MATLAB_ALL) $(MATLAB_GEOD_PRIVATE)
+EXTRA_DIST = Makefile.mk CMakeLists.txt $(MATLAB_ALL) $(MATLAB_LEGACY_ALL)
diff --git a/matlab/Makefile.in b/matlab/Makefile.in
index 9fe2954..38f9e26 100644
--- a/matlab/Makefile.in
+++ b/matlab/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994-2013 Free Software Foundation, Inc.
@@ -251,90 +251,106 @@ target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
+MATLAB_FILES = \
+$(srcdir)/geographiclib/Contents.m \
+$(srcdir)/geographiclib/cassini_fwd.m \
+$(srcdir)/geographiclib/cassini_inv.m \
+$(srcdir)/geographiclib/defaultellipsoid.m \
+$(srcdir)/geographiclib/ecc2flat.m \
+$(srcdir)/geographiclib/eqdazim_fwd.m \
+$(srcdir)/geographiclib/eqdazim_inv.m \
+$(srcdir)/geographiclib/flat2ecc.m \
+$(srcdir)/geographiclib/gedistance.m \
+$(srcdir)/geographiclib/gedoc.m \
+$(srcdir)/geographiclib/geocent_fwd.m \
+$(srcdir)/geographiclib/geocent_inv.m \
+$(srcdir)/geographiclib/geodarea.m \
+$(srcdir)/geographiclib/geoddistance.m \
+$(srcdir)/geographiclib/geoddoc.m \
+$(srcdir)/geographiclib/geodreckon.m \
+$(srcdir)/geographiclib/geoid_height.m \
+$(srcdir)/geographiclib/geoid_load.m \
+$(srcdir)/geographiclib/gereckon.m \
+$(srcdir)/geographiclib/gnomonic_fwd.m \
+$(srcdir)/geographiclib/gnomonic_inv.m \
+$(srcdir)/geographiclib/loccart_fwd.m \
+$(srcdir)/geographiclib/loccart_inv.m \
+$(srcdir)/geographiclib/mgrs_fwd.m \
+$(srcdir)/geographiclib/mgrs_inv.m \
+$(srcdir)/geographiclib/polarst_fwd.m \
+$(srcdir)/geographiclib/polarst_inv.m \
+$(srcdir)/geographiclib/projdoc.m \
+$(srcdir)/geographiclib/tranmerc_fwd.m \
+$(srcdir)/geographiclib/tranmerc_inv.m \
+$(srcdir)/geographiclib/utmups_fwd.m \
+$(srcdir)/geographiclib/utmups_inv.m
+
+MATLAB_PRIVATE = \
+$(srcdir)/geographiclib/private/A1m1f.m \
+$(srcdir)/geographiclib/private/A2m1f.m \
+$(srcdir)/geographiclib/private/A3coeff.m \
+$(srcdir)/geographiclib/private/A3f.m \
+$(srcdir)/geographiclib/private/AngDiff.m \
+$(srcdir)/geographiclib/private/AngNormalize.m \
+$(srcdir)/geographiclib/private/AngNormalize2.m \
+$(srcdir)/geographiclib/private/AngRound.m \
+$(srcdir)/geographiclib/private/C1f.m \
+$(srcdir)/geographiclib/private/C1pf.m \
+$(srcdir)/geographiclib/private/C2f.m \
+$(srcdir)/geographiclib/private/C3coeff.m \
+$(srcdir)/geographiclib/private/C3f.m \
+$(srcdir)/geographiclib/private/C4coeff.m \
+$(srcdir)/geographiclib/private/C4f.m \
+$(srcdir)/geographiclib/private/G4coeff.m \
+$(srcdir)/geographiclib/private/GeoRotation.m \
+$(srcdir)/geographiclib/private/SinCosSeries.m \
+$(srcdir)/geographiclib/private/cbrtx.m \
+$(srcdir)/geographiclib/private/cvmgt.m \
+$(srcdir)/geographiclib/private/eatanhe.m \
+$(srcdir)/geographiclib/private/geoid_file.m \
+$(srcdir)/geographiclib/private/geoid_load_file.m \
+$(srcdir)/geographiclib/private/norm2.m \
+$(srcdir)/geographiclib/private/sumx.m \
+$(srcdir)/geographiclib/private/swap.m \
+$(srcdir)/geographiclib/private/tauf.m \
+$(srcdir)/geographiclib/private/taupf.m
+
+MATLAB_LEGACY = \
+$(srcdir)/geographiclib-legacy/Contents.m \
+$(srcdir)/geographiclib-legacy/geocentricforward.m \
+$(srcdir)/geographiclib-legacy/geocentricreverse.m \
+$(srcdir)/geographiclib-legacy/geodesicdirect.m \
+$(srcdir)/geographiclib-legacy/geodesicinverse.m \
+$(srcdir)/geographiclib-legacy/geodesicline.m \
+$(srcdir)/geographiclib-legacy/geoidheight.m \
+$(srcdir)/geographiclib-legacy/localcartesianforward.m \
+$(srcdir)/geographiclib-legacy/localcartesianreverse.m \
+$(srcdir)/geographiclib-legacy/mgrsforward.m \
+$(srcdir)/geographiclib-legacy/mgrsreverse.m \
+$(srcdir)/geographiclib-legacy/polygonarea.m \
+$(srcdir)/geographiclib-legacy/utmupsforward.m \
+$(srcdir)/geographiclib-legacy/utmupsreverse.m
+
 MATLAB_INTERFACE = \
-$(srcdir)/geodesicdirect.cpp \
-$(srcdir)/geodesicinverse.cpp \
-$(srcdir)/geodesicline.cpp \
-$(srcdir)/geoidheight.cpp \
-$(srcdir)/mgrsforward.cpp \
-$(srcdir)/mgrsreverse.cpp \
-$(srcdir)/utmupsforward.cpp \
-$(srcdir)/utmupsreverse.cpp \
-$(srcdir)/geocentricforward.cpp \
-$(srcdir)/geocentricreverse.cpp \
-$(srcdir)/localcartesianforward.cpp \
-$(srcdir)/localcartesianreverse.cpp \
-$(srcdir)/polygonarea.cpp
-
-MATLAB_DOC = \
-$(srcdir)/geodesicdirect.m \
-$(srcdir)/geodesicinverse.m \
-$(srcdir)/geodesicline.m \
-$(srcdir)/geoidheight.m \
-$(srcdir)/mgrsforward.m \
-$(srcdir)/mgrsreverse.m \
-$(srcdir)/utmupsforward.m \
-$(srcdir)/utmupsreverse.m \
-$(srcdir)/geocentricforward.m \
-$(srcdir)/geocentricreverse.m \
-$(srcdir)/localcartesianforward.m \
-$(srcdir)/localcartesianreverse.m \
-$(srcdir)/polygonarea.m
-
-MATLAB_COMPILESCRIPT = $(srcdir)/geographiclibinterface.m
-MATLAB_GEOD = \
-$(srcdir)/geoddoc.m \
-$(srcdir)/geodreckon.m \
-$(srcdir)/geoddistance.m \
-$(srcdir)/geodarea.m \
-$(srcdir)/defaultellipsoid.m \
-$(srcdir)/ecc2flat.m \
-$(srcdir)/flat2ecc.m \
-$(srcdir)/geodproj.m \
-$(srcdir)/eqdazim_fwd.m \
-$(srcdir)/eqdazim_inv.m \
-$(srcdir)/cassini_fwd.m \
-$(srcdir)/cassini_inv.m \
-$(srcdir)/tranmerc_fwd.m \
-$(srcdir)/tranmerc_inv.m \
-$(srcdir)/gnomonic_fwd.m \
-$(srcdir)/gnomonic_inv.m \
-$(srcdir)/utm_fwd.m \
-$(srcdir)/utm_inv.m \
-$(srcdir)/gedoc.m \
-$(srcdir)/gereckon.m \
-$(srcdir)/gedistance.m
-
-MATLAB_GEOD_PRIVATE = \
-$(srcdir)/private/A1m1f.m \
-$(srcdir)/private/A2m1f.m \
-$(srcdir)/private/A3coeff.m \
-$(srcdir)/private/A3f.m \
-$(srcdir)/private/AngDiff.m \
-$(srcdir)/private/AngNormalize2.m \
-$(srcdir)/private/AngNormalize.m \
-$(srcdir)/private/AngRound.m \
-$(srcdir)/private/atanhee.m \
-$(srcdir)/private/C1f.m \
-$(srcdir)/private/C1pf.m \
-$(srcdir)/private/C2f.m \
-$(srcdir)/private/C3coeff.m \
-$(srcdir)/private/C3f.m \
-$(srcdir)/private/C4coeff.m \
-$(srcdir)/private/G4coeff.m \
-$(srcdir)/private/C4f.m \
-$(srcdir)/private/cbrt.m \
-$(srcdir)/private/cvmgt.m \
-$(srcdir)/private/SinCosNorm.m \
-$(srcdir)/private/SinCosSeries.m \
-$(srcdir)/private/sumx.m \
-$(srcdir)/private/swap.m
-
-MATLAB_ALL = $(MATLAB_INTERFACE) $(MATLAB_DOC) $(MATLAB_COMPILESCRIPT) \
-	$(MATLAB_GEOD)
-
-matlabdir = $(libexecdir)/GeographicLib/matlab
-EXTRA_DIST = Makefile.mk CMakeLists.txt $(MATLAB_ALL) $(MATLAB_GEOD_PRIVATE)
+$(srcdir)/geographiclib-legacy/geographiclibinterface.m \
+$(srcdir)/geographiclib-legacy/geocentricforward.cpp \
+$(srcdir)/geographiclib-legacy/geocentricreverse.cpp \
+$(srcdir)/geographiclib-legacy/geodesicdirect.cpp \
+$(srcdir)/geographiclib-legacy/geodesicinverse.cpp \
+$(srcdir)/geographiclib-legacy/geodesicline.cpp \
+$(srcdir)/geographiclib-legacy/geoidheight.cpp \
+$(srcdir)/geographiclib-legacy/localcartesianforward.cpp \
+$(srcdir)/geographiclib-legacy/localcartesianreverse.cpp \
+$(srcdir)/geographiclib-legacy/mgrsforward.cpp \
+$(srcdir)/geographiclib-legacy/mgrsreverse.cpp \
+$(srcdir)/geographiclib-legacy/polygonarea.cpp \
+$(srcdir)/geographiclib-legacy/utmupsforward.cpp \
+$(srcdir)/geographiclib-legacy/utmupsreverse.cpp
+
+MATLAB_ALL = $(MATLAB_FILES) $(MATLAB_PRIVATE)
+MATLAB_LEGACY_ALL = $(MATLAB_LEGACY) $(MATLAB_INTERFACE)
+matlabdir = $(DESTDIR)$(datadir)/matlab
+EXTRA_DIST = Makefile.mk CMakeLists.txt $(MATLAB_ALL) $(MATLAB_LEGACY_ALL)
 all: all-am
 
 .SUFFIXES:
@@ -526,9 +542,11 @@ uninstall-am:
 
 
 install:
-	$(INSTALL) -d $(DESTDIR)$(matlabdir)/private
-	$(INSTALL) -m 644 $(MATLAB_ALL) $(DESTDIR)$(matlabdir)
-	$(INSTALL) -m 644 $(MATLAB_GEOD_PRIVATE) $(DESTDIR)$(matlabdir)/private
+	$(INSTALL) -d $(matlabdir)/geographiclib/private
+	$(INSTALL) -d $(matlabdir)/geographiclib-legacy
+	$(INSTALL) -m 644 $(MATLAB_FILES) $(matlabdir)/geographiclib
+	$(INSTALL) -m 644 $(MATLAB_PRIVATE) $(matlabdir)/geographiclib/private
+	$(INSTALL) -m 644 $(MATLAB_LEGACY_ALL) $(matlabdir)/geographiclib-legacy
 
 clean-local:
 	rm -rf *.mex* *.oct
diff --git a/matlab/Makefile.mk b/matlab/Makefile.mk
index 6210286..af33546 100644
--- a/matlab/Makefile.mk
+++ b/matlab/Makefile.mk
@@ -1,31 +1,23 @@
-FUNCTIONS = utmupsforward utmupsreverse mgrsforward mgrsreverse \
-	geodesicdirect geodesicinverse geodesicline \
-	geoidheight geocentricforward geocentricreverse \
-	localcartesianforward localcartesianreverse polygonarea
+MATLAB_FILES = $(wildcard geographiclib/*.m)
+MATLAB_PRIVATE = $(wildcard geographiclib/private/*.m)
+MATLAB_LEGACY = $(wildcard geographiclib-legacy/*.m) \
+	$(wildcard geographiclib-legacy/*.cpp)
 
-MATLAB_COMPILESCRIPT = geographiclibinterface.m
-
-MATLAB_GEOD = geoddoc.m geodreckon.m geoddistance.m geodarea.m \
-	defaultellipsoid.m ecc2flat.m flat2ecc.m \
-	geodproj.m eqdazim_fwd.m eqdazim_inv.m cassini_fwd.m cassini_inv.m \
-	tranmerc_fwd.m tranmerc_inv.m gnomonic_fwd.m gnomonic_inv.m \
-	utm_fwd.m utm_inv.m
-
-MATLAB_GEOD_PRIVATE = $(wildcard private/*.m)
-
-MATLABFILES = $(addsuffix .cpp,$(FUNCTIONS)) $(addsuffix .m,$(FUNCTIONS)) \
-	 $(MATLAB_COMPILESCRIPT) $(MATLAB_GEOD)
-
-DEST = $(PREFIX)/libexec/GeographicLib/matlab
+DEST = $(PREFIX)/share/matlab
 INSTALL = install -b
 
 all:
 	@:
 
 install:
-	test -d $(DEST)/private || mkdir -p $(DEST)/private
-	$(INSTALL) -m 644 $(MATLABFILES) $(DEST)/
-	$(INSTALL) -m 644 $(MATLAB_GEOD_PRIVATE) $(DEST)/private/
+	test -d $(DEST)/geographiclib/private || \
+		mkdir -p $(DEST)/geographiclib/private
+	test -d $(DEST)/geographiclib-legacy || \
+		mkdir -p $(DEST)/geographiclib-legacy
+	$(INSTALL) -m 644 $(MATLAB_FILES) $(DEST)/geographiclib
+	$(INSTALL) -m 644 $(MATLAB_PRIVATE) $(DEST)/geographiclib/private/
+	$(INSTALL) -m 644 $(MATLAB_LEGACY) $(DEST)/geographiclib-legacy
+
 clean:
 	rm -f *.mex* *.oct
 
diff --git a/matlab/cassini_inv.m b/matlab/cassini_inv.m
deleted file mode 100644
index 785febb..0000000
--- a/matlab/cassini_inv.m
+++ /dev/null
@@ -1,46 +0,0 @@
-function [lat, lon, azi, rk] = cassini_inv(lat0, lon0, x, y, ellipsoid)
-%CASSINI_INV  Inverse Cassini-Soldner projection
-%
-%   [LAT, LON] = CASSINI_INV(LAT0, LON0, X, Y)
-%   [LAT, LON, AZI, RK] = CASSINI_INV(LAT0, LON0, X, Y, ELLIPSOID)
-%
-%   performs the inverse Cassini-Soldner projection of points (X,Y) to
-%   (LAT,LON) using (LAT0,LON0) as the center of projection.  These input
-%   arguments can be scalars or arrays of equal size.  The ELLIPSOID vector
-%   is of the form [a, e], where a is the equatorial radius in meters, e is
-%   the eccentricity.  If ellipsoid is omitted, the WGS84 ellipsoid (more
-%   precisely, the value returned by DEFAULTELLIPSOID) is used.  GEODPROJ
-%   defines the projection and gives the restrictions on the allowed ranges
-%   of the arguments.  The forward projection is given by CASSINI_FWD.
-%
-%   AZI and RK give metric properties of the projection at (LAT,LON); AZI
-%   is the azimuth of the easting (X) direction and RK is the reciprocal of
-%   the northing (Y) scale.  The scale in the easting direction is 1.
-%
-%   LAT0, LON0, LAT, LON, AZI are in degrees.  The projected coordinates X,
-%   Y are in meters (more precisely the units used for the equatorial
-%   radius).  RK is dimensionless.
-%
-%   This routine depends on the MATLAB File Exchange package "Geodesics on
-%   an ellipsoid of revolution":
-%
-%     http://www.mathworks.com/matlabcentral/fileexchange/39108
-%
-%   See also GEODPROJ, CASSINI_FWD, GEODRECKON, DEFAULTELLIPSOID.
-
-% Copyright (c) Charles Karney (2012) <charles at karney.com>.
-%
-% This file was distributed with GeographicLib 1.29.
-
-  if nargin < 4, error('Too few input arguments'), end
-  if nargin < 5, ellipsoid = defaultellipsoid; end
-  try
-    [~] = lat0 + lon0 + x + y;
-  catch err
-    error('lat0, lon0, x, y have incompatible sizes')
-  end
-
-  [lat1, lon1, azi0] = geodreckon(lat0, lon0, y, 0, ellipsoid);
-  [lat, lon, azi, ~, ~, rk] = ...
-      geodreckon(lat1, lon1, x, azi0 + 90, ellipsoid);
-end
diff --git a/matlab/ecc2flat.m b/matlab/ecc2flat.m
deleted file mode 100644
index 846edea..0000000
--- a/matlab/ecc2flat.m
+++ /dev/null
@@ -1,10 +0,0 @@
-function f = ecc2flat(e)
-%ECC2FLAT   Convert the eccentricity of an ellipsoid to its flattening
-%
-%  F = ECC2FLAT(E) returns the flattening given the eccentricity.
-%
-%   See also FLAT2ECC.
-
-  e2 = e.^2;
-  f = e2 ./ (1 + sqrt(1 - e2));
-end
diff --git a/matlab/flat2ecc.m b/matlab/flat2ecc.m
deleted file mode 100644
index 801a7e0..0000000
--- a/matlab/flat2ecc.m
+++ /dev/null
@@ -1,9 +0,0 @@
-function e = flat2ecc(f)
-%FLAT2ECC   Convert the flattening of an ellipsoid to its eccentricity
-%
-%  E = FLAT2ECC(F) returns the eccentricity given the flattening.
-%
-%   See also ECC2FLAT.
-
-  e = sqrt(f .* (2 - f));
-end
diff --git a/matlab/geocentricforward.m b/matlab/geocentricforward.m
deleted file mode 100644
index b721db1..0000000
--- a/matlab/geocentricforward.m
+++ /dev/null
@@ -1,36 +0,0 @@
-function geocentricforward(~, ~, ~)
-%geocentricforward  Convert geographic coordinates to geocentric
-%
-%   [geocentric, rot] = geocentricforward(geodetic)
-%   [geocentric, rot] = geocentricforward(geodetic, a, f)
-%
-%   geodetic is an M x 3 or M x 2 matrix of geodetic coordinates
-%       lat = geodetic(:,1) in degrees
-%       lon = geodetic(:,2) in degrees
-%       h = geodetic(:,3) in meters (default 0 m)
-%
-%   geocentric is an M x 3 matrix of geocentric coordinates
-%       x = geocentric(:,1) in meters
-%       y = geocentric(:,2) in meters
-%       z = geocentric(:,3) in meters
-%   rot is an M x 9 matrix
-%       M = rot(:,1:9) rotation matrix in row major order.  Pre-multiplying
-%           a unit vector in local cartesian coordinates (east, north, up)
-%           by M transforms the vector to geocentric coordinates.
-%
-%   a = major radius (meters)
-%   f = flattening (0 means a sphere)
-%   If a and f are omitted, the WGS84 values are used.
-%
-% This is an interface to the GeographicLib C++ routine
-%     Geocentric::Forward
-% See the documentation on this function for more information:
-% http://geographiclib.sf.net/html/classGeographicLib_1_1Geocentric.html
-  error('Error: executing .m file instead of compiled routine');
-end
-% geocentricforward.m
-% Matlab .m file for geographic to geocentric conversions
-%
-% Copyright (c) Charles Karney (2011) <charles at karney.com> and licensed
-% under the MIT/X11 License.  For more information, see
-% http://geographiclib.sourceforge.net/
diff --git a/matlab/geocentricreverse.m b/matlab/geocentricreverse.m
deleted file mode 100644
index 91a2990..0000000
--- a/matlab/geocentricreverse.m
+++ /dev/null
@@ -1,37 +0,0 @@
-function geocentricreverse(~, ~, ~)
-%geocentricreverse  Convert geocentric coordinates to geographic
-%
-%   [geodetic, rot] = geocentricreverse(geocentric)
-%   [geodetic, rot] = geocentricreverse(geocentric, a, f)
-%
-%   geocentric is an M x 3 matrix of geocentric coordinates
-%       x = geocentric(:,1) in meters
-%       y = geocentric(:,2) in meters
-%       z = geocentric(:,3) in meters
-%
-%   geodetic is an M x 3 matrix of geodetic coordinates
-%       lat = geodetic(:,1) in degrees
-%       lon = geodetic(:,2) in degrees
-%       h = geodetic(:,3) in meters
-%   rot is an M x 9 matrix
-%       M = rot(:,1:9) rotation matrix in row major order.  Pre-multiplying
-%           a unit vector in  geocentric coordinates by the transpose of M
-%           transforms the vector to local cartesian coordinates
-%           (east, north, up).
-%
-%   a = major radius (meters)
-%   f = flattening (0 means a sphere)
-%   If a and f are omitted, the WGS84 values are used.
-%
-% This is an interface to the GeographicLib C++ routine
-%     Geocentric::Reverse
-% See the documentation on this function for more information:
-% http://geographiclib.sf.net/html/classGeographicLib_1_1Geocentric.html
-  error('Error: executing .m file instead of compiled routine');
-end
-% geocentricreverse.m
-% Matlab .m file for geocentric to geographic conversions
-%
-% Copyright (c) Charles Karney (2011) <charles at karney.com> and licensed
-% under the MIT/X11 License.  For more information, see
-% http://geographiclib.sourceforge.net/
diff --git a/matlab/geodesicdirect.m b/matlab/geodesicdirect.m
deleted file mode 100644
index d4ff5c5..0000000
--- a/matlab/geodesicdirect.m
+++ /dev/null
@@ -1,51 +0,0 @@
-function geodesicdirect(~, ~, ~)
-%geodesicdirect  Solve direct geodesic problem
-%
-%   [latlong, aux] = geodesicdirect(geodesic)
-%   [latlong, aux] = geodesicdirect(geodesic, a, f)
-%
-%   geodesic is an M x 4 matrix
-%       latitude of point 1 = latlong(:,1) in degrees
-%       longitude of point 1 = latlong(:,2) in degrees
-%       azimuth at point 1 = latlong(:,3) in degrees
-%       distance to point 2 = latlong(:,4) in meters
-%
-%   latlong is an M x 3 matrix
-%       latitude of point 2 = geodesic(:,1) in degrees
-%       longitude of point 2 = geodesic(:,2) in degrees
-%       azimuth at point 2 = geodesic(:,3) in degrees
-%   aux is an M x 5 matrix
-%       spherical arc length = aux(:,1) in degrees
-%       reduced length = aux(:,2) in meters
-%       geodesic scale 1 to 2 = aux(:,3)
-%       geodesic scale 2 to 1 = aux(:,4)
-%       area under geodesic = aux(:,5) in meters^2
-%
-%   a = major radius (meters)
-%   f = flattening (0 means a sphere)
-%   If a and f are omitted, the WGS84 values are used.
-%
-% The algorithm used in this function is given in
-%
-%     C. F. F. Karney, Algorithms for geodesics,
-%     J. Geodesy 87, 43-55 (2013);
-%     https://dx.doi.org/10.1007/s00190-012-0578-z
-%     Addenda: http://geographiclib.sf.net/geod-addenda.html
-%
-% This is an interface to the GeographicLib C++ routine
-%     Geodesic::Direct
-% See the documentation on this function for more information:
-% http://geographiclib.sf.net/html/classGeographicLib_1_1Geodesic.html
-%
-% A native MATLAB implementation is available as GEODRECKON.
-%
-% See also GEODRECKON.
-
-  error('Error: executing .m file instead of compiled routine');
-end
-% geodesicdirect.m
-% Matlab .m file for solving direct geodesic problem
-%
-% Copyright (c) Charles Karney (2010-2011) <charles at karney.com> and licensed
-% under the MIT/X11 License.  For more information, see
-% http://geographiclib.sourceforge.net/
diff --git a/matlab/geodesicinverse.m b/matlab/geodesicinverse.m
deleted file mode 100644
index f8be843..0000000
--- a/matlab/geodesicinverse.m
+++ /dev/null
@@ -1,51 +0,0 @@
-function geodesicinverse(~, ~, ~)
-%geodesicinverse  Solve inverse geodesic problem
-%
-%   [geodesic, aux] = geodesicinverse(latlong)
-%   [geodesic, aux] = geodesicinverse(latlong, a, f)
-%
-%   latlong is an M x 4 matrix
-%       latitude of point 1 = latlong(:,1) in degrees
-%       longitude of point 1 = latlong(:,2) in degrees
-%       latitude of point 2 = latlong(:,3) in degrees
-%       longitude of point 2 = latlong(:,4) in degrees
-%
-%   geodesic is an M x 3 matrix
-%       azimuth at point 1 = geodesic(:,1) in degrees
-%       azimuth at point 2 = geodesic(:,2) in degrees
-%       distance between points 1 and 2 = geodesic(:,3) in meters
-%   aux is an M x 5 matrix
-%       spherical arc length = aux(:,1) in degrees
-%       reduced length = aux(:,2) in meters
-%       geodesic scale 1 to 2 = aux(:,3)
-%       geodesic scale 2 to 1 = aux(:,4)
-%       area under geodesic = aux(:,5) in meters^2
-%
-%   a = major radius (meters)
-%   f = flattening (0 means a sphere)
-%   If a and f are omitted, the WGS84 values are used.
-%
-% The algorithm used in this function is given in
-%
-%     C. F. F. Karney, Algorithms for geodesics,
-%     J. Geodesy 87, 43-55 (2013);
-%     https://dx.doi.org/10.1007/s00190-012-0578-z
-%     Addenda: http://geographiclib.sf.net/geod-addenda.html
-%
-% This is an interface to the GeographicLib C++ routine
-%     Geodesic::Inverse
-% See the documentation on this function for more information:
-% http://geographiclib.sf.net/html/classGeographicLib_1_1Geodesic.html
-%
-% A native MATLAB implementation is available as GEODDISTANCE.
-%
-% See also GEODDISTANCE.
-
-  error('Error: executing .m file instead of compiled routine');
-end
-% geodesicinverse.m
-% Matlab .m file for solving inverse geodesic problem
-%
-% Copyright (c) Charles Karney (2010-2011) <charles at karney.com> and licensed
-% under the MIT/X11 License.  For more information, see
-% http://geographiclib.sourceforge.net/
diff --git a/matlab/geodesicline.m b/matlab/geodesicline.m
deleted file mode 100644
index 67b001c..0000000
--- a/matlab/geodesicline.m
+++ /dev/null
@@ -1,54 +0,0 @@
-function geodesicline(~, ~, ~, ~, ~, ~)
-%geodesicline  Compute points along a geodesic
-%
-%   [latlong, aux] = geodesicline(lat1, lon1, azi1, distances)
-%   [latlong, aux] = geodesicline(lat1, lon1, azi1, distances, a, f)
-%
-%   lat1 is the latitude of point 1 (scalar) in degrees
-%   lon1 is the longitude of point 1 (scalar) in degrees
-%   azi1 is the azimuth at point 1 (scalar) in degrees
-%   distances is an M x 1 vector of distances to point 2 in meters
-%
-%   latlong is an M x 3 matrix
-%       latitude of point 2 = geodesic(:,1) in degrees
-%       longitude of point 2 = geodesic(:,2) in degrees
-%       azimuth at point 2 = geodesic(:,3) in degrees
-%   aux is an M x 5 matrix
-%       spherical arc length = aux(:,1) in degrees
-%       reduced length = aux(:,2) in meters
-%       geodesic scale 1 to 2 = aux(:,3)
-%       geodesic scale 2 to 1 = aux(:,4)
-%       area under geodesic = aux(:,5) in meters^2
-%
-%   a = major radius (meters)
-%   f = flattening (0 means a sphere)
-%   If a and f are omitted, the WGS84 values are used.
-%
-%   The result is the same as produced by
-%       geodesicdirect([repmat([lat1, lon1, azi1],size(distances)), ...
-%                       distances], a, f)
-%
-% The algorithm used in this function is given in
-%
-%     C. F. F. Karney, Algorithms for geodesics,
-%     J. Geodesy 87, 43-55 (2013);
-%     https://dx.doi.org/10.1007/s00190-012-0578-z
-%     Addenda: http://geographiclib.sf.net/geod-addenda.html
-%
-% This is an interface to the GeographicLib C++ routine
-%     GeodesicLine::Position
-% See the documentation on this function for more information:
-% http://geographiclib.sf.net/html/classGeographicLib_1_1GeodesicLine.html
-%
-% A native MATLAB implementation is available as GEODRECKON.
-%
-% See also GEODRECKON.
-
-  error('Error: executing .m file instead of compiled routine');
-end
-% geodesicline.m
-% Matlab .m file for computing points along a geodesic
-%
-% Copyright (c) Charles Karney (2010-2011) <charles at karney.com> and licensed
-% under the MIT/X11 License.  For more information, see
-% http://geographiclib.sourceforge.net/
diff --git a/matlab/geodproj.m b/matlab/geodproj.m
deleted file mode 100644
index 26b8ef9..0000000
--- a/matlab/geodproj.m
+++ /dev/null
@@ -1,139 +0,0 @@
-function geodproj
-%GEODPROJ  Geodesic projections for an ellipsoid
-%
-%   This package implements four projections based on geodesics:
-%     * the azimuthal equidistant projection (eqdazim)
-%     * the Cassini-Soldner projection (cassini)
-%     * the transverse Mercator projection (tranmerc)
-%     * the ellipsoidal gnomonic projection (gnomonic)
-%
-%   The package implements the forward projection (from geographic to
-%   projected coordinates) and inverse projection (from projected to
-%   geographic coordinates) with abbreviated function names (listed in
-%   parentheses in the list above) suffixed by _FWD and _INV.  In addition,
-%   implementations of the UTM projection are provided with UTM_FWD and
-%   UTM_INV.  For each function, metric properties of the projection are
-%   also returned.
-%
-%   This package requires the availability of MATLAB File Exchange package
-%   "Geodesics on an ellipsoid of revolution" for performing the necessary
-%   geodesic computations:
-%
-%     http://www.mathworks.com/matlabcentral/fileexchange/39108
-%
-%   The azimuthal equidistant inverse projection is a geodesic projection
-%   defined by
-%
-%     [S,AZI0] = GEODDISTANCE(LAT0,LON0,LAT,LON)
-%     X = S.*SIND(AZI0), Y = S.*COSD(AZI0)
-%
-%   Thus all distances and azimuths relative to the center point are
-%   correct.
-%
-%   The Cassini-Solder projection is a rectangular geodesic projection
-%   whose inverse is specified by
-%
-%     [LAT1,LON1,AZI1] = GEODRECKON(LAT0,LON0,Y,0)
-%     [LAT,LON] = GEODRECKON(LAT1,LON1,X,AZI1+90)
-%
-%   Cassini-Soldner is a transverse cylindrical projection where the
-%   meridian LON0 maps to a straight line with constant scale and distances
-%   perpendicular to the central meridian are true.  Cassini-Soldner was
-%   widely used for large scale maps until about 1930 (when it was
-%   supplanted by various conformal projections, in particular, by the
-%   transverse Mercator projection).
-%
-%   The transverse Mercator projection is also a cylindrical projection
-%   which maps the central meridian to a straight line at constant scale.
-%   However the behavior either side of the central meridian is determined
-%   by the condition of conformality.  The implementation used in this
-%   package is based on the series method described in
-%
-%     C. F. F. Karney, Transverse Mercator with an accuracy of a few
-%     nanometers, J. Geodesy 85(8), 475-485 (Aug. 2011);
-%     Addenda: http://geographiclib.sf.net/tm-addenda.html
-%
-%   The ellipsoidal gnomonic projection is defined by
-%
-%     [~,AZI0,~,~,m,M] = GEODDISTANCE(LAT0,LON0,LAT,LON)
-%     RHO = m./M, X = RHO.*SIND(AZI0), Y = RHO.*COSD(AZI0)
-%
-%   Obviously this is an azimuthal projection.  It also enjoys approximately
-%   the property of the spherical gnomonic projection, that geodesics map
-%   to straight lines.  The projection is derived in Section 8 of
-%
-%     C. F. F. Karney, Algorithms for geodesics,
-%     J. Geodesy 87, 43-55 (2013);
-%     https://dx.doi.org/10.1007/s00190-012-0578-z
-%     Addenda: http://geographiclib.sf.net/geod-addenda.html
-%
-%   The parameters of the ellipsoid are specified by the optional ELLIPSOID
-%   argument to the routines.  This is a two-element vector of the form
-%   [a,e], where a is the equatorial radius, e is the eccentricity e =
-%   sqrt(a^2-b^2)/a, and b is the polar semi-axis.  Typically, a and b are
-%   measured in meters and the linear and area quantities returned by the
-%   routines are then in meters and meters^2.  However, other units can be
-%   employed.  If ELLIPSOID is omitted, then the WGS84 ellipsoid (more
-%   precisely, the value returned by DEFAULTELLIPSOID) is assumed [6378137,
-%   0.0818191908426215] corresponding to a = 6378137 meters and a
-%   flattening f = (a-b)/a = 1/298.257223563.  The flattening and
-%   eccentricity are related by
-%
-%       e = sqrt(f * (2 - f))
-%       f = e^2 / (1 + sqrt(1 - e^2))
-%
-%   (The functions ECC2FLAT and FLAT2ECC implement these conversions.)  For
-%   a sphere, set e = 0; for a prolate ellipsoid (b > a), specify e as a
-%   pure imaginary number.
-%
-%   All angles (latitude, longitude, azimuth) are measured in degrees with
-%   latitudes increasing northwards, longitudes increasing eastwards, and
-%   azimuths measured clockwise from north.  For a point at a pole, the
-%   azimuth is defined by keeping the longitude fixed, writing lat =
-%   +/-(90-eps), and taking the limit eps -> 0+.
-%
-%   Restrictions on the inputs:
-%     * All latitudes must lie in [-90, 90].
-%     * All longitudes and azimuths must lie in [-540, 540).  On output,
-%       these quantities lie in [-180, 180).
-%     * The equatorial radius, a, must be positive.
-%     * The eccentricity, e, should be satisfy abs(e) < 0.2 in order to
-%       retain full accuracy (this corresponds to flattenings satisfying
-%       abs(f) <= 1/50, approximately).  This condition holds for most
-%       applications in geodesy.
-%
-%   These routines are fully vectorized so that their speed is competitive
-%   with the compiled C++ code.  These MATLAB versions are transcriptions
-%   of several C++ classes provided by GeographicLib which is available at
-%
-%     http://geographiclib.sf.net
-%
-%   The routines duplicate some of the functionality of the EQDAZIM,
-%   CASSINISTD, TRANMERC, and GNOMONIC projections in the the MATLAB
-%   mapping toolbox.  The major improvements offered by this package are
-%
-%     * The azimuthal equidistant and gnomonic projections are defined
-%       for the ellipsoid (instead of just for the sphere).
-%     * The Cassini-Soldner projection is essentially exact (instead of
-%       being defined in terms of an approximate series).
-%     * The transverse Mercator projection uses a much more accurate
-%       series which greatly extends its domain of applicability.
-%
-%   The primary importance of the two azimuthal projections is that they
-%   offer a convenient way of solving various geometrical problems on the
-%   ellipsoid.  In particular the azimuthal equidistant projection allows
-%   problems associated with determining maritime boundaries to be solved
-%   easily.  Similarly the gnomonic projection allows the intersection of
-%   two geodesics to be determined quickly.
-%
-%   See also EQDAZIM_FWD, EQDAZIM_INV, CASSINI_FWD, CASSINI_INV,
-%     TRANMERC_FWD, TRANMERC_INV, GNOMONIC_FWD, GNOMONIC_INV, UTM_FWD,
-%     UTM_INV, DEFAULTELLIPSOID, ECC2FLAT, FLAT2ECC, GEODDISTANCE,
-%     GEODRECKON.
-
-% Copyright (c) Charles Karney (2012) <charles at karney.com>.
-%
-% This file was distributed with GeographicLib 1.29.
-
-  help geodproj
-end
diff --git a/matlab/geographiclib-legacy/Contents.m b/matlab/geographiclib-legacy/Contents.m
new file mode 100644
index 0000000..061cd74
--- /dev/null
+++ b/matlab/geographiclib-legacy/Contents.m
@@ -0,0 +1,38 @@
+% GeographicLib legacy functions
+% Version 1.42 2015-04-27
+%
+%   The functions in this directory are DEPRECATED.  They are wrapper
+%   routines for the GeographicLib toolbox, which is available at
+%
+%     href="http://www.mathworks.com/matlabcentral/fileexchange/50605
+%
+%   Directly using the GeographicLib toolbox provides greater functionality
+%   and flexiblility.
+%
+% Geodesics
+%   geodesicdirect         - Wrapper for geodreckon
+%   geodesicinverse        - Wrapper for geoddistance
+%   geodesicline           - Another wrapper for geodreckon
+%   polygonarea            - Wrapper for geodarea
+%
+% Grid systems
+%   utmupsforward          - Wrapper for utmups_fwd
+%   utmupsreverse          - Wrapper for utmups_inv
+%   mgrsforward            - Wrapper for mgrs_fwd
+%   mgrsreverse            - Wrapper for mgrs_inv
+%
+% Geoid lookup
+%   geoidheight            - Wrapper for geoid_height
+%
+% Geometric transformations
+%   geocentricforward      - Wrapper for geocent_fwd
+%   geocentricreverse      - Wrapper for geocent_inv
+%   localcartesianforward  - Wrapper for loccart_fwd
+%   localcartesianreverse  - Wrapper for loccart_inv
+%
+% Deprecated
+%   geographiclibinterface - Compile interface code (DEPRECATED)
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
diff --git a/matlab/geocentricforward.cpp b/matlab/geographiclib-legacy/geocentricforward.cpp
similarity index 100%
rename from matlab/geocentricforward.cpp
rename to matlab/geographiclib-legacy/geocentricforward.cpp
diff --git a/matlab/geographiclib-legacy/geocentricforward.m b/matlab/geographiclib-legacy/geocentricforward.m
new file mode 100644
index 0000000..38f724b
--- /dev/null
+++ b/matlab/geographiclib-legacy/geocentricforward.m
@@ -0,0 +1,46 @@
+function [geocentric, rot] = geocentricforward(geodetic, a, f)
+%GEOCENTRICFORWARD  Wrapper for geocent_fwd
+%
+%   [geocentric, rot] = GEOCENTRICFORWARD(geodetic)
+%   [geocentric, rot] = GEOCENTRICFORWARD(geodetic, a, f)
+%
+%   This is a legacy function to replace a compiled interface function of
+%   the same name.  This now calls geocent_fwd which is implemented as
+%   native Matlab code.
+%
+%   geodetic is an M x 3 or M x 2 matrix of geodetic coordinates
+%       lat = geodetic(:,1) in degrees
+%       lon = geodetic(:,2) in degrees
+%       h = geodetic(:,3) in meters (default 0 m)
+%
+%   geocentric is an M x 3 matrix of geocentric coordinates
+%       X = geocentric(:,1) in meters
+%       Y = geocentric(:,2) in meters
+%       Z = geocentric(:,3) in meters
+%   rot is an M x 9 matrix
+%       M = rot(:,1:9) rotation matrix in row major order.  Pre-multiplying
+%           a unit vector in local cartesian coordinates (east, north, up)
+%           by M transforms the vector to geocentric coordinates.
+%
+%   See also GEOCENT_FWD.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  if (nargin < 2)
+    ellipsoid = defaultellipsoid;
+  elseif (nargin < 3)
+    ellipsoid = [a, 0];
+  else
+    ellipsoid = [a, flat2ecc(f)];
+  end
+  if size(geodetic,2) < 3
+    h = 0;
+  else
+    h = geodetic(:,3);
+  end
+  [X, Y, Z, M] = geocent_fwd(geodetic(:,1), geodetic(:,2), h, ellipsoid);
+  geocentric = [X, Y, Z];
+  rot = reshape(permute(M, [3, 2, 1]), [], 9);
+end
diff --git a/matlab/geocentricreverse.cpp b/matlab/geographiclib-legacy/geocentricreverse.cpp
similarity index 100%
rename from matlab/geocentricreverse.cpp
rename to matlab/geographiclib-legacy/geocentricreverse.cpp
diff --git a/matlab/geographiclib-legacy/geocentricreverse.m b/matlab/geographiclib-legacy/geocentricreverse.m
new file mode 100644
index 0000000..7c3c65e
--- /dev/null
+++ b/matlab/geographiclib-legacy/geocentricreverse.m
@@ -0,0 +1,47 @@
+function [geodetic, rot] = geocentricreverse(geocentric, a, f)
+%GEOCENTRICREVERSE  Wrapper for geocent_inv
+%
+%   [geodetic, rot] = GEOCENTRICREVERSE(geocentric)
+%   [geodetic, rot] = GEOCENTRICREVERSE(geocentric, a, f)
+%
+%   This is a legacy function to replace a compiled interface function of
+%   the same name.  This now calls geocent_inv which is implemented as
+%   native Matlab code.
+%
+%   geocentric is an M x 3 matrix of geocentric coordinates
+%       X = geocentric(:,1) in meters
+%       Y = geocentric(:,2) in meters
+%       Z = geocentric(:,3) in meters
+%
+%   geodetic is an M x 3 matrix of geodetic coordinates
+%       lat = geodetic(:,1) in degrees
+%       lon = geodetic(:,2) in degrees
+%       h = geodetic(:,3) in meters
+%   rot is an M x 9 matrix
+%       M = rot(:,1:9) rotation matrix in row major order.  Pre-multiplying
+%           a unit vector in  geocentric coordinates by the transpose of M
+%           transforms the vector to local cartesian coordinates
+%           (east, north, up).
+%
+%   a = major radius (meters)
+%   f = flattening (0 means a sphere)
+%   If a and f are omitted, the WGS84 values are used.
+%
+%   See also GEOCENT_INV.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  if (nargin < 2)
+    ellipsoid = defaultellipsoid;
+  elseif (nargin < 3)
+    ellipsoid = [a, 0];
+  else
+    ellipsoid = [a, flat2ecc(f)];
+  end
+  [lat, lon, h, M] = geocent_inv(geocentric(:,1), geocentric(:,2), ...
+                                 geocentric(:,3), ellipsoid);
+  geodetic = [lat, lon, h];
+  rot = reshape(permute(M, [3, 2, 1]), [], 9);
+end
diff --git a/matlab/geodesicdirect.cpp b/matlab/geographiclib-legacy/geodesicdirect.cpp
similarity index 100%
rename from matlab/geodesicdirect.cpp
rename to matlab/geographiclib-legacy/geodesicdirect.cpp
diff --git a/matlab/geographiclib-legacy/geodesicdirect.m b/matlab/geographiclib-legacy/geodesicdirect.m
new file mode 100644
index 0000000..d4ddb28
--- /dev/null
+++ b/matlab/geographiclib-legacy/geodesicdirect.m
@@ -0,0 +1,50 @@
+function [latlong, aux] = geodesicdirect(geodesic, a, f)
+%GEODESICDIRECT  Wrapper for geodreckon
+%
+%   [latlong, aux] = GEODESICDIRECT(geodesic)
+%   [latlong, aux] = GEODESICDIRECT(geodesic, a, f)
+%
+%   This is a legacy function to replace a compiled interface function of
+%   the same name.  This now calls geodreckon which is implemented as
+%   native Matlab code.
+%
+%   geodesic is an M x 4 matrix
+%       latitude of point 1 = latlong(:,1) in degrees
+%       longitude of point 1 = latlong(:,2) in degrees
+%       azimuth at point 1 = latlong(:,3) in degrees
+%       distance to point 2 = latlong(:,4) in meters
+%
+%   latlong is an M x 3 matrix
+%       latitude of point 2 = geodesic(:,1) in degrees
+%       longitude of point 2 = geodesic(:,2) in degrees
+%       azimuth at point 2 = geodesic(:,3) in degrees
+%   aux is an M x 5 matrix
+%       spherical arc length = aux(:,1) in degrees
+%       reduced length = aux(:,2) in meters
+%       geodesic scale 1 to 2 = aux(:,3)
+%       geodesic scale 2 to 1 = aux(:,4)
+%       area under geodesic = aux(:,5) in meters^2
+%
+%   a = major radius (meters)
+%   f = flattening (0 means a sphere)
+%   If a and f are omitted, the WGS84 values are used.
+%
+%   See also GEODRECKON.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  if (nargin < 2)
+    ellipsoid = defaultellipsoid;
+  elseif (nargin < 3)
+    ellipsoid = [a, 0];
+  else
+    ellipsoid = [a, flat2ecc(f)];
+  end
+  [lat2, lon2, azi2, S12, m12, M12, M21, a12] = geodreckon ...
+      (geodesic(:,1), geodesic(:,2), geodesic(:,4), geodesic(:,3), ...
+       ellipsoid);
+  latlong = [lat2, lon2, azi2];
+  aux = [a12, m12, M12, M21, S12];
+end
diff --git a/matlab/geodesicinverse.cpp b/matlab/geographiclib-legacy/geodesicinverse.cpp
similarity index 100%
rename from matlab/geodesicinverse.cpp
rename to matlab/geographiclib-legacy/geodesicinverse.cpp
diff --git a/matlab/geographiclib-legacy/geodesicinverse.m b/matlab/geographiclib-legacy/geodesicinverse.m
new file mode 100644
index 0000000..09074a0
--- /dev/null
+++ b/matlab/geographiclib-legacy/geodesicinverse.m
@@ -0,0 +1,49 @@
+function [geodesic, aux] = geodesicinverse(latlong, a, f)
+%GEODESICINVERSE  Wrapper for geoddistance
+%
+%   [geodesic, aux] = GEODESICINVERSE(latlong)
+%   [geodesic, aux] = GEODESICINVERSE(latlong, a, f)
+%
+%   This is a legacy function to replace a compiled interface function of
+%   the same name.  This now calls geoddistance which is implemented as
+%   native Matlab code.
+%
+%   latlong is an M x 4 matrix
+%       latitude of point 1 = latlong(:,1) in degrees
+%       longitude of point 1 = latlong(:,2) in degrees
+%       latitude of point 2 = latlong(:,3) in degrees
+%       longitude of point 2 = latlong(:,4) in degrees
+%
+%   geodesic is an M x 3 matrix
+%       azimuth at point 1 = geodesic(:,1) in degrees
+%       azimuth at point 2 = geodesic(:,2) in degrees
+%       distance between points 1 and 2 = geodesic(:,3) in meters
+%   aux is an M x 5 matrix
+%       spherical arc length = aux(:,1) in degrees
+%       reduced length = aux(:,2) in meters
+%       geodesic scale 1 to 2 = aux(:,3)
+%       geodesic scale 2 to 1 = aux(:,4)
+%       area under geodesic = aux(:,5) in meters^2
+%
+%   a = major radius (meters)
+%   f = flattening (0 means a sphere)
+%   If a and f are omitted, the WGS84 values are used.
+%
+%   See also GEODDISTANCE.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  if (nargin < 2)
+    ellipsoid = defaultellipsoid;
+  elseif (nargin < 3)
+    ellipsoid = [a, 0];
+  else
+    ellipsoid = [a, flat2ecc(f)];
+  end
+  [s12, azi1, azi2, S12, m12, M12, M21, a12] = geoddistance ...
+      (latlong(:,1), latlong(:,2), latlong(:,3), latlong(:,4), ellipsoid);
+  geodesic = [azi1, azi2, s12];
+  aux = [a12, m12, M12, M21, S12];
+end
diff --git a/matlab/geodesicline.cpp b/matlab/geographiclib-legacy/geodesicline.cpp
similarity index 100%
rename from matlab/geodesicline.cpp
rename to matlab/geographiclib-legacy/geodesicline.cpp
diff --git a/matlab/geographiclib-legacy/geodesicline.m b/matlab/geographiclib-legacy/geodesicline.m
new file mode 100644
index 0000000..e0dd680
--- /dev/null
+++ b/matlab/geographiclib-legacy/geodesicline.m
@@ -0,0 +1,52 @@
+function [latlong, aux] = geodesicline(lat1, lon1, azi1, distances, a, f)
+%GEODESICLINE  Another wrapper for geodreckon
+%
+%   [latlong, aux] = GEODESICLINE(lat1, lon1, azi1, distances)
+%   [latlong, aux] = GEODESICLINE(lat1, lon1, azi1, distances, a, f)
+%
+%   This is a legacy function to replace a compiled interface function of
+%   the same name.  This now calls geodreckon which is implemented as
+%   native Matlab code.
+%
+%   lat1 is the latitude of point 1 (scalar) in degrees
+%   lon1 is the longitude of point 1 (scalar) in degrees
+%   azi1 is the azimuth at point 1 (scalar) in degrees
+%   distances is an M x 1 vector of distances to point 2 in meters
+%
+%   latlong is an M x 3 matrix
+%       latitude of point 2 = geodesic(:,1) in degrees
+%       longitude of point 2 = geodesic(:,2) in degrees
+%       azimuth at point 2 = geodesic(:,3) in degrees
+%   aux is an M x 5 matrix
+%       spherical arc length = aux(:,1) in degrees
+%       reduced length = aux(:,2) in meters
+%       geodesic scale 1 to 2 = aux(:,3)
+%       geodesic scale 2 to 1 = aux(:,4)
+%       area under geodesic = aux(:,5) in meters^2
+%
+%   a = major radius (meters)
+%   f = flattening (0 means a sphere)
+%   If a and f are omitted, the WGS84 values are used.
+%
+%   The result is the same as produced by
+%       geodesicdirect([repmat([lat1, lon1, azi1],size(distances)), ...
+%                       distances], a, f)
+%
+%   See also GEODRECKON.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  if (nargin < 5)
+    ellipsoid = defaultellipsoid;
+  elseif (nargin < 6)
+    ellipsoid = [a, 0];
+  else
+    ellipsoid = [a, flat2ecc(f)];
+  end
+  [lat2, lon2, azi2, S12, m12, M12, M21, a12] = ...
+      geodreckon(lat1, lon1, distances, azi1, ellipsoid);
+  latlong = [lat2, lon2, azi2];
+  aux = [a12, m12, M12, M21, S12];
+end
diff --git a/matlab/geographiclibinterface.m b/matlab/geographiclib-legacy/geographiclibinterface.m
similarity index 51%
rename from matlab/geographiclibinterface.m
rename to matlab/geographiclib-legacy/geographiclibinterface.m
index 1bcfca4..fa98c3c 100644
--- a/matlab/geographiclibinterface.m
+++ b/matlab/geographiclib-legacy/geographiclibinterface.m
@@ -1,39 +1,40 @@
 function geographiclibinterface(incdir, libdir)
-% geographiclibinterface  Use mex to compile interface to GeographicLib
+%GEOGRAPHICLIBINTERFACE  Compile interface code (DEPRECATED)
 %
-%   geographiclibinterface
-%   geographiclibinterface(INSTALLDIR)
-%   geographiclibinterface(INCDIR, LIBDIR)
+%   GEOGRAPHICLIBINTERFACE
+%   GEOGRAPHICLIBINTERFACE(installdir)
+%   GEOGRAPHICLIBINTERFACE(incdir, libdir)
 %
-% With one argument the library is looked for in INSTALLDIR/lib and the
-% include files in INSTALLDIR/include.
+%   This function is DEPRECATED because native Matlab implementations are
+%   available for all the functions.  It and the associated C++ wrapper
+%   code will be removed at some point in 2016.
 %
-% With no arguments, INSTALLDIR is taked to be '/usr/local', on Unix and
-% Linux systems, and 'C:/Program Files/GeographicLib', on Windows systems
+%   With one argument GEOGRAPHICLIBINTERFACE looks for the compiled library
+%   in installdir/lib and the include files in installdir/include.
 %
-% With two arguments, the library is looked for in LIBDIR and the include
-% files in INCDIR.
+%   With no arguments, installdir is taked to be '/usr/local', on Unix and
+%   Linux systems, and 'C:/Program Files/GeographicLib', on Windows systems
 %
-% This has been tested with
+%   With two arguments, the library is looked for in libdir and the include
+%   files in incdir.
 %
-%   Octave 3.2.3 and g++ 4.4.4 under Linux
-%   Octave 3.6.4 and g++ 4.8.3 under Linux
-%   Matlab 2007a and Visual Studio 2005 under Windows
-%   Matlab 2008a and Visual Studio 2005 under Windows
-%   Matlab 2008a and Visual Studio 2008 under Windows (*)
-%   Matlab 2010b and Visual Studio 2005 under Windows
-%   Matlab 2010b and Visual Studio 2008 under Windows (*)
-%   Matlab 2010b and Visual Studio 2010 under Windows
-%   Matlab 2013b and Visual Studio 2012 under Windows
-%   Matlab 2014b and Mac OSX 10.10 (Yosemite)
+%   This has been tested with
 %
-% (*) Note that geoidheight compiled with Visual Studio 2008 causes Matlab
-%     to CRASH.  The crash happens on the second call.
+%     Octave 3.2.3 and g++ 4.4.4 under Linux
+%     Octave 3.6.4 and g++ 4.8.3 under Linux
+%     Matlab 2007a and Visual Studio 2005 under Windows
+%     Matlab 2008a and Visual Studio 2005 under Windows
+%     Matlab 2008a and Visual Studio 2008 under Windows (*)
+%     Matlab 2010b and Visual Studio 2005 under Windows
+%     Matlab 2010b and Visual Studio 2008 under Windows (*)
+%     Matlab 2010b and Visual Studio 2010 under Windows
+%     Matlab 2013b and Visual Studio 2012 under Windows
+%     Matlab 2014b and Mac OSX 10.10 (Yosemite)
 %
-% Run 'mex -setup' to configure the C++ compiler for Matlab to use.
-%
-% Copyright (c) Charles Karney (2010-2011) <charles at karney.com> and licensed
-% under the MIT/X11 License.  For more information, see
+%   Run 'mex -setup' to configure the C++ compiler for Matlab to use.
+
+% Copyright (c) Charles Karney (2010-2014) <charles at karney.com> and
+% licensed under the MIT/X11 License.  For more information, see
 % http://geographiclib.sf.net/html/other.html#matlab
 
   funs = {'geodesicdirect', 'geodesicinverse', 'geodesicline', ...
diff --git a/matlab/geoidheight.cpp b/matlab/geographiclib-legacy/geoidheight.cpp
similarity index 100%
rename from matlab/geoidheight.cpp
rename to matlab/geographiclib-legacy/geoidheight.cpp
diff --git a/matlab/geographiclib-legacy/geoidheight.m b/matlab/geographiclib-legacy/geoidheight.m
new file mode 100644
index 0000000..2800ed9
--- /dev/null
+++ b/matlab/geographiclib-legacy/geoidheight.m
@@ -0,0 +1,39 @@
+function height = geoidheight(latlong, geoidname, geoiddir)
+%GEOIDHEIGHT  Wrapper for geoid_height
+%
+%   height = GEOIDHEIGHT(latlong)
+%   height = GEOIDHEIGHT(latlong, geoidname, geoiddir)
+%
+%   This is a legacy function to replace a compiled interface function of
+%   the same name.  This now calls geoid_height which is implemented as
+%   native Matlab code.  (Note that, unlike the compiled interface, this
+%   wrapper function does not return the gradient of the geoid height; this
+%   is now a deprecated feature of the Geoid class.)
+%
+%   latlong is an M x 2 matrix
+%       latitude = latlong(:,1) in degrees
+%       longitude = latlong(:,2) in degrees
+%   geoidname is the name of the geoid; choices are (default egm96-5)
+%       egm84-30  egm84-15
+%       egm96-15  egm96-5
+%       egm2008-5 egm2008-2_5 egm2008-1
+%   geoiddir is the directory containing the geoid models (default empty
+%       string meaning system default)
+%
+%   height is an M x 1 matrix
+%       geoidheight = height(:,1) height of geoid in meters
+%
+%   See also GEOID_HEIGHT.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  if nargin < 2
+    geoidname = '';
+  end
+  if nargin < 3
+    geoiddir = '';
+  end
+  height = geoid_height(latlong(:,1), latlong(:,2), geoidname, geoiddir);
+end
diff --git a/matlab/localcartesianforward.cpp b/matlab/geographiclib-legacy/localcartesianforward.cpp
similarity index 100%
rename from matlab/localcartesianforward.cpp
rename to matlab/geographiclib-legacy/localcartesianforward.cpp
diff --git a/matlab/geographiclib-legacy/localcartesianforward.m b/matlab/geographiclib-legacy/localcartesianforward.m
new file mode 100644
index 0000000..9de21c8
--- /dev/null
+++ b/matlab/geographiclib-legacy/localcartesianforward.m
@@ -0,0 +1,63 @@
+function [cartesian, rot] = localcartesianforward(origin, geodetic, a, f)
+%LOCALCARTESIANFORWARD  Wrapper for loccart_fwd
+%
+%   [cartesian, rot] = LOCALCARTESIANFORWARD(origin, geodetic)
+%   [cartesian, rot] = LOCALCARTESIANFORWARD(origin, geodetic, a, f)
+%
+%   This is a legacy function to replace a compiled interface function of
+%   the same name.  This now calls loccart_fwd which is implemented as
+%   native Matlab code.
+%
+%   origin is a 1 x 3 or 1 x 2 matrix
+%       lat0 = origin(1,1) in degrees
+%       lon0 = origin(1,2) in degrees
+%       h0 = origin(1,3) in meters (default 0 m)
+%   geodetic is an M x 3 or M x 2 matrix of geodetic coordinates
+%       lat = geodetic(:,1) in degrees
+%       lon = geodetic(:,2) in degrees
+%       h = geodetic(:,3) in meters (default 0 m)
+%
+%   cartesian is an M x 3 matrix of local cartesian coordinates
+%       x = cartesian(:,1) in meters
+%       y = cartesian(:,2) in meters
+%       z = cartesian(:,3) in meters
+%   rot is an M x 9 matrix
+%       M = rot(:,1:9) rotation matrix in row major order.  Pre-multiplying
+%           a unit vector in local cartesian coordinates at (lat, lon, h)
+%           by M transforms the vector to local cartesian coordinates at
+%           (lat0, lon0, h0)
+%
+%   a = major radius (meters)
+%   f = flattening (0 means a sphere)
+%   If a and f are omitted, the WGS84 values are used.
+%
+%   See also LOCCART_FWD.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  if (nargin < 3)
+    ellipsoid = defaultellipsoid;
+  elseif (nargin < 4)
+    ellipsoid = [a, 0];
+  else
+    ellipsoid = [a, flat2ecc(f)];
+  end
+  if size(geodetic,2) < 3
+    h = 0;
+  else
+    h = geodetic(:,3);
+  end
+  if length(origin(:)) == 2
+    h0 = 0;
+  elseif length(origin(:)) == 3
+    h0 = origin(3);
+  else
+    error('origin is not vector of length 2 or 3')
+  end
+  [x, y, z, M] = loccart_fwd(origin(1), origin(2), h0, ...
+                             geodetic(:,1), geodetic(:,2), h, ellipsoid);
+  cartesian = [x, y, z];
+  rot = reshape(permute(M, [3, 2, 1]), [], 9);
+end
diff --git a/matlab/localcartesianreverse.cpp b/matlab/geographiclib-legacy/localcartesianreverse.cpp
similarity index 100%
rename from matlab/localcartesianreverse.cpp
rename to matlab/geographiclib-legacy/localcartesianreverse.cpp
diff --git a/matlab/geographiclib-legacy/localcartesianreverse.m b/matlab/geographiclib-legacy/localcartesianreverse.m
new file mode 100644
index 0000000..d9067a4
--- /dev/null
+++ b/matlab/geographiclib-legacy/localcartesianreverse.m
@@ -0,0 +1,59 @@
+function [geodetic, rot] = localcartesianreverse(origin, cartesian, a, f)
+%LOCALCARTESIANREVERSE  Wrapper for loccart_inv
+%
+%   [geodetic, rot] = LOCALCARTESIANREVERSE(origin, cartesian)
+%   [geodetic, rot] = LOCALCARTESIANREVERSE(origin, cartesian, a, f)
+%
+%   This is a legacy function to replace a compiled interface function of
+%   the same name.  This now calls loccart_inv which is implemented as
+%   native Matlab code.
+%
+%   origin is a 1 x 3 or 1 x 2 matrix
+%       lat0 = origin(1,1) in degrees
+%       lon0 = origin(1,2) in degrees
+%       h0 = origin(1,3) in meters (default 0 m)
+%   cartesian is an M x 3 matrix of local cartesian coordinates
+%       x = cartesian(:,1) in meters
+%       y = cartesian(:,2) in meters
+%       z = cartesian(:,3) in meters
+%
+%   geodetic is an M x 3 matrix of geodetic coordinates
+%       lat = geodetic(:,1) in degrees
+%       lon = geodetic(:,2) in degrees
+%       h = geodetic(:,3) in meters
+%   rot is an M x 9 matrix
+%       M = rot(:,1:9) rotation matrix in row major order.  Pre-multiplying
+%           a unit vector in local cartesian coordinates at (lat0, lon0,
+%           h0) by the transpose of M transforms the vector to local
+%           cartesian coordinates at (lat, lon, h).
+%
+%   a = major radius (meters)
+%   f = flattening (0 means a sphere)
+%   If a and f are omitted, the WGS84 values are used.
+%
+%   See also LOCCART_INV.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  if (nargin < 3)
+    ellipsoid = defaultellipsoid;
+  elseif (nargin < 4)
+    ellipsoid = [a, 0];
+  else
+    ellipsoid = [a, flat2ecc(f)];
+  end
+  if length(origin(:)) == 2
+    h0 = 0;
+  elseif length(origin(:)) == 3
+    h0 = origin(3);
+  else
+    error('origin is not vector of length 2 or 3')
+  end
+  [lat, lon, h, M] = ...
+      loccart_inv(origin(1), origin(2), h0, ...
+                  cartesian(:,1), cartesian(:,2), cartesian(:,3), ellipsoid);
+  geodetic = [lat, lon, h];
+  rot = reshape(permute(M, [3, 2, 1]), [], 9);
+end
diff --git a/matlab/mgrsforward.cpp b/matlab/geographiclib-legacy/mgrsforward.cpp
similarity index 95%
rename from matlab/mgrsforward.cpp
rename to matlab/geographiclib-legacy/mgrsforward.cpp
index bd35731..a307ef5 100644
--- a/matlab/mgrsforward.cpp
+++ b/matlab/geographiclib-legacy/mgrsforward.cpp
@@ -48,8 +48,8 @@ void mexFunction( int nlhs, mxArray* plhs[],
     prec = int(rprec);
     if (double(prec) != rprec)
       mexErrMsgTxt("Precision is not an integer.");
-    if (prec < 0 || prec > 11)
-      mexErrMsgTxt("Precision outside the legal range [0, 11].");
+    if (prec < -1 || prec > 11)
+      mexErrMsgTxt("Precision outside the legal range [-1, 11].");
   }
 
   mwSize m = mxGetM(prhs[0]);
diff --git a/matlab/geographiclib-legacy/mgrsforward.m b/matlab/geographiclib-legacy/mgrsforward.m
new file mode 100644
index 0000000..c6bd551
--- /dev/null
+++ b/matlab/geographiclib-legacy/mgrsforward.m
@@ -0,0 +1,34 @@
+function mgrs = mgrsforward(utmups, prec)
+%MGRSFORWARD  Wrapper for mgrs_fwd
+%
+%   mgrs = MGRSFORWARD(utmups)
+%   mgrs = MGRSFORWARD(utmups, prec)
+%
+%   This is a legacy function to replace a compiled interface function of
+%   the same name.  This now calls mgrs_fwd which is implemented as native
+%   Matlab code.
+%
+%   utmups is an M x 4 matrix
+%       easting = utmups(:,1) in meters
+%       northing = utmups(:,2) in meters
+%       zone = utmups(:,3)
+%       hemi = utmups(:,4)
+%
+%   zone = 0 for UPS, zone = [1,60] for UTM
+%   hemi = 0 for southern hemisphere, hemi = 1 for northern hemisphere
+%   prec = half the number of trailing digits in the MGRS string
+%          (default 5)
+%
+%   mgrs is a M x 1 cell array of MGRS strings.
+%
+%   See also MGRS_FWD.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  if nargin < 2
+    prec = 5;
+  end
+  mgrs = mgrs_fwd(utmups(:,1), utmups(:,2), utmups(:,3), utmups(:,4), prec);
+end
diff --git a/matlab/mgrsreverse.cpp b/matlab/geographiclib-legacy/mgrsreverse.cpp
similarity index 98%
rename from matlab/mgrsreverse.cpp
rename to matlab/geographiclib-legacy/mgrsreverse.cpp
index 0709ace..93c2555 100644
--- a/matlab/mgrsreverse.cpp
+++ b/matlab/geographiclib-legacy/mgrsreverse.cpp
@@ -70,7 +70,7 @@ void mexFunction( int nlhs, mxArray* plhs[],
       mexWarnMsgTxt(e.what());
       x[i] = y[i] = Math::NaN<double>();
       zone[i] = UTMUPS::INVALID; hemi[i] = 0;
-      if (precp) prec[i] = -1;
+      if (precp) prec[i] = -2;
     }
   }
 }
diff --git a/matlab/mgrsreverse.m b/matlab/geographiclib-legacy/mgrsreverse.m
similarity index 54%
rename from matlab/mgrsreverse.m
rename to matlab/geographiclib-legacy/mgrsreverse.m
index da76426..4a86024 100644
--- a/matlab/mgrsreverse.m
+++ b/matlab/geographiclib-legacy/mgrsreverse.m
@@ -1,7 +1,11 @@
-function mgrsreverse(~)
-%mgrsreverse  Convert UTM/UPS coordinates to MGRS
+function [utmups, prec] = mgrsreverse(mgrs)
+%MGRSREVERSE  Wrapper for mgrs_inv
 %
-%   [utmups, prec] = mgrsreverse(mgrs)
+%   [utmups, prec] = MGRSREVERSE(mgrs)
+%
+%   This is a legacy function to replace a compiled interface function of
+%   the same name.  This now calls mgrs_inv which is implemented as native
+%   Matlab code.
 %
 %   mgrs is a M x 1 cell array of MGRS strings, e.g.,
 %       mgrsreverse({ '38SMB4488'; '12TUK3393' })
@@ -22,15 +26,12 @@ function mgrsreverse(~)
 %   The position is the center of the MGRS square.  To obtain the
 %   SW corner subtract 0.5 * 10^(5-prec) from the easting and northing.
 %
-% This is an interface to the GeographicLib C++ routine
-%     MGRS::Reverse
-% See the documentation on this function for more information:
-% http://geographiclib.sf.net/html/classGeographicLib_1_1MGRS.html
-  error('Error: executing .m file instead of compiled routine');
-end
-% mgrsreverse.m
-% Matlab .m file for MGRS to UTM/UPS conversions
+%   See also MGRS_INV.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
 %
-% Copyright (c) Charles Karney (2010-2011) <charles at karney.com> and licensed
-% under the MIT/X11 License.  For more information, see
-% http://geographiclib.sourceforge.net/
+% This file was distributed with GeographicLib 1.42.
+
+  [x, y, z, h, prec] = mgrs_inv(mgrs);
+  utmups = [x, y, z, h];
+end
diff --git a/matlab/polygonarea.cpp b/matlab/geographiclib-legacy/polygonarea.cpp
similarity index 100%
rename from matlab/polygonarea.cpp
rename to matlab/geographiclib-legacy/polygonarea.cpp
diff --git a/matlab/geographiclib-legacy/polygonarea.m b/matlab/geographiclib-legacy/polygonarea.m
new file mode 100644
index 0000000..ad15a74
--- /dev/null
+++ b/matlab/geographiclib-legacy/polygonarea.m
@@ -0,0 +1,42 @@
+function [area, perimeter] = polygonarea(latlong, a, f)
+%POLYGONAREA  Wrapper for geodarea
+%
+%   [area, perimeter] = POLYGONAREA(latlong)
+%   [area, perimeter] = POLYGONAREA(latlong, a, f)
+%
+%   This is a legacy function to replace a compiled interface function of
+%   the same name.  This now calls geodarea which is implemented as native
+%   Matlab code.
+%
+%   latlong is an M x 2 matrix
+%       latitude of vertices = latlong(:,1) in degrees
+%       longitude of vertices = latlong(:,2) in degrees
+%
+%   area is the area in meters^2
+%   perimeter is the perimeter in meters
+%
+%   a = major radius (meters)
+%   f = flattening (0 means a sphere)
+%   If a and f are omitted, the WGS84 values are used.
+%
+%   Only simple polygons (which do not intersect themselves) are supported.
+%   There is no need to "close" the polygon.  Counter-clockwise traversal
+%   counts as a positive area.  A polygon may encircle one or both poles.
+%   The total area of the WGS84 ellipsoid is given by
+%     8 * polygonarea([ 0 0; 0 90; 90 0 ])
+%
+%   See also GEODAREA.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  if (nargin < 2)
+    ellipsoid = defaultellipsoid;
+  elseif (nargin < 3)
+    ellipsoid = [a, 0];
+  else
+    ellipsoid = [a, flat2ecc(f)];
+  end
+ [area, perimeter] = geodarea(latlong(:,1), latlong(:,2), ellipsoid);
+end
diff --git a/matlab/utmupsforward.cpp b/matlab/geographiclib-legacy/utmupsforward.cpp
similarity index 100%
rename from matlab/utmupsforward.cpp
rename to matlab/geographiclib-legacy/utmupsforward.cpp
diff --git a/matlab/utmupsforward.m b/matlab/geographiclib-legacy/utmupsforward.m
similarity index 51%
rename from matlab/utmupsforward.m
rename to matlab/geographiclib-legacy/utmupsforward.m
index 874d4ab..7ab1f8a 100644
--- a/matlab/utmupsforward.m
+++ b/matlab/geographiclib-legacy/utmupsforward.m
@@ -1,8 +1,12 @@
-function utmupsforward(~, ~)
-%utmupsforward  Convert geographic coordinates to UTM/UPS
+function [utmups, scale] = utmupsforward(latlong, setzone)
+%UTMUPSFORWARD  Wrapper for utmups_fwd
 %
-%   [utmups, scale] = utmupsforward(latlong)
-%   [utmups, scale] = utmupsforward(latlong, setzone)
+%   [utmups, scale] = UTMUPSFORWARD(latlong)
+%   [utmups, scale] = UTMUPSFORWARD(latlong, setzone)
+%
+%   This is a legacy function to replace a compiled interface function of
+%   the same name.  This now calls utmups_fwd which is implemented as
+%   native Matlab code.
 %
 %   latlong is an M x 2 matrix
 %       latitude = latlong(:,1) in degrees
@@ -26,15 +30,17 @@ function utmupsforward(~, ~)
 %       -1, use the standard assigment (the default)
 %       -2, use closest UTM zone
 %
-% This is an interface to the GeographicLib C++ routine
-%     UTMUPS::Forward
-% See the documentation on this function for more information:
-% http://geographiclib.sf.net/html/classGeographicLib_1_1UTMUPS.html
-  error('Error: executing .m file instead of compiled routine');
-end
-% utmupsforward.m
-% Matlab .m file for geographic to UTM/UPS conversions
+%   See also UTMUPS_FWD.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
 %
-% Copyright (c) Charles Karney (2010-2011) <charles at karney.com> and licensed
-% under the MIT/X11 License.  For more information, see
-% http://geographiclib.sourceforge.net/
+% This file was distributed with GeographicLib 1.42.
+
+  if nargin < 2
+    setzone = -1;
+  end
+  [x, y, zone, northp, gam, k] = ...
+      utmups_fwd(latlong(:,1), latlong(:,2), setzone);
+  utmups = [x, y, zone, northp];
+  scale = [gam, k];
+end
diff --git a/matlab/utmupsreverse.cpp b/matlab/geographiclib-legacy/utmupsreverse.cpp
similarity index 100%
rename from matlab/utmupsreverse.cpp
rename to matlab/geographiclib-legacy/utmupsreverse.cpp
diff --git a/matlab/geographiclib-legacy/utmupsreverse.m b/matlab/geographiclib-legacy/utmupsreverse.m
new file mode 100644
index 0000000..cb94a1d
--- /dev/null
+++ b/matlab/geographiclib-legacy/utmupsreverse.m
@@ -0,0 +1,36 @@
+function [latlong, scale] = utmupsreverse(utmups)
+%UTMUPSREVERSE  Wrapper for utmups_inv
+%
+%   [latlong, scale] = UTMUPSREVERSE(utmups)
+%
+%   This is a legacy function to replace a compiled interface function of
+%   the same name.  This now calls utmups_inv which is implemented as
+%   native Matlab code.
+%
+%   utmups is an M x 4 matrix
+%       easting = utmups(:,1) in meters
+%       northing = utmups(:,2) in meters
+%       zone = utmups(:,3)
+%       hemi = utmups(:,4)
+%
+%   zone = 0 for UPS, zone = [1,60] for UTM
+%   hemi = 0 for southern hemisphere, hemi = 1 for northern hemisphere.
+%
+%   latlong is an M x 2 matrix
+%       latitude = latlong(:,1) in degrees
+%       longitude = latlong(:,2) in degrees
+%   scale is an M x 2 matrix
+%       gamma = scale(:,1) meridian convergence in degrees
+%       k = scale(:,2) scale
+%
+%   See also UTMUPS_INV.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  [lat, lon, gam, k] = ...
+      utmups_inv(utmups(:,1), utmups(:,2), utmups(:,3), utmups(:,4));
+  latlong = [lat, lon];
+  scale = [gam, k];
+end
diff --git a/matlab/geographiclib/Contents.m b/matlab/geographiclib/Contents.m
new file mode 100644
index 0000000..beabc8a
--- /dev/null
+++ b/matlab/geographiclib/Contents.m
@@ -0,0 +1,95 @@
+% GeographicLib toolbox
+% Version 1.42 2015-04-27
+%
+%   This toolbox provides native MATLAB implementations of a subset of the
+%   C++ library, GeographicLib.  Key components of this toolbox are
+%
+%     * Geodesics, direct, inverse, area calculations.
+%     * Projections, transverse Mercator, polar stereographic, etc.
+%     * Grid systems, UTM, UPS, MGRS.
+%     * Geoid lookup, egm84, egm96, egm2008 geoids supported.
+%     * Geometric transformations, geocentric, local cartesian.
+%     * Great ellipse, direct, inverse, area calculations.
+%
+%   All the functions are vectorized and so offer speeds comparable to
+%   compiled C++ code when operating on arrays.  Additional information is
+%   available in the documentation for the GeographicLib, which is
+%   available at
+%
+%       http://geographiclib.sf.net/html
+%
+%   Some common features of these functions:
+%     * Angles (latitude, longitude, azimuth, meridian convergence) are
+%       measured in degrees.
+%     * Distances are measured in meters, areas in meters^2.
+%     * Latitudes must lie in [-90,90] and longitudes and azimuths in
+%       [-540,540).  However most routines don't check that this condition
+%       holds.  (Exceptions are the grid system and geoid functions.  These
+%       return NaNs for invalid inputs.)
+%     * The ellipsoid is specified as [a, e], where a = equatorial radius
+%       and e = eccentricity.  The eccentricity can be pure imaginary to
+%       denote a prolate ellipsoid.
+%     * Keep abs(e) < 0.2 (i.e., abs(f) <= 1/50) for full double precision
+%       accuracy.
+%
+%   There is some overlap between this toolbox and MATLAB's Mapping
+%   Toolbox.  However, this toolbox offers:
+%     * better accuracy;
+%     * treatment of oblate and prolate ellipsoid;
+%     * guaranteed convergence for geoddistance;
+%     * calculation of area and differential properties of geodesics;
+%     * ellipsoidal versions of the equidistant azimuthal and gnomonic
+%       projections.
+%
+% Function summary:
+%
+% Geodesics
+%   geoddistance     - Distance between points on an ellipsoid
+%   geodreckon       - Point at specified azimuth, range on an ellipsoid
+%   geodarea         - Surface area of polygon on an ellipsoid
+%
+% Projections
+%   tranmerc_fwd     - Forward transverse Mercator projection
+%   tranmerc_inv     - Inverse transverse Mercator projection
+%   polarst_fwd      - Forward polar stereographic projection
+%   polarst_inv      - Inverse polar stereographic projection
+%   eqdazim_fwd      - Forward azimuthal equidistant projection
+%   eqdazim_inv      - Inverse azimuthal equidistant projection
+%   cassini_fwd      - Forward Cassini-Soldner projection
+%   cassini_inv      - Inverse Cassini-Soldner projection
+%   gnomonic_fwd     - Forward ellipsoidal gnomonic projection
+%   gnomonic_inv     - Inverse ellipsoidal gnomonic projection
+%
+% Grid systems
+%   utmups_fwd       - Convert to UTM/UPS system
+%   utmups_inv       - Convert from UTM/UPS system
+%   mgrs_fwd         - Convert UTM/UPS coordinates to MGRS
+%   mgrs_inv         - Convert MGRS to UTM/UPS coordinates
+%
+% Geoid lookup
+%   geoid_height     - Compute the height of the geoid
+%   geoid_load       - Load a geoid model
+%
+% Geometric transformations
+%   geocent_fwd      - Conversion from geographic to geocentric coordinates
+%   geocent_inv      - Conversion from geocentric to geographic coordinates
+%   loccart_fwd      - Convert geographic to local cartesian coordinates
+%   loccart_inv      - Convert local cartesian to geographic coordinates
+%
+% Great ellipses
+%   gedistance       - Great ellipse distance on an ellipsoid
+%   gereckon         - Point along great ellipse at given azimuth and range
+%
+% Utility
+%   defaultellipsoid - Return the WGS84 ellipsoid
+%   ecc2flat         - Convert eccentricity to flattening
+%   flat2ecc         - Convert flattening to eccentricity
+%
+% Documentation
+%   geoddoc          - Geodesics on an ellipsoid of revolution
+%   projdoc          - Projections for an ellipsoid
+%   gedoc            - Great ellipses on an ellipsoid of revolution
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
diff --git a/matlab/cassini_fwd.m b/matlab/geographiclib/cassini_fwd.m
similarity index 58%
rename from matlab/cassini_fwd.m
rename to matlab/geographiclib/cassini_fwd.m
index 09a9b03..6e841bb 100644
--- a/matlab/cassini_fwd.m
+++ b/matlab/geographiclib/cassini_fwd.m
@@ -1,43 +1,37 @@
 function [x, y, azi, rk] = cassini_fwd(lat0, lon0, lat, lon, ellipsoid)
 %CASSINI_FWD  Forward Cassini-Soldner projection
 %
-%   [X, Y] = CASSINI_FWD(LAT0, LON0, LAT, LON)
-%   [X, Y, AZI, RK] = CASSINI_FWD(LAT0, LON0, LAT, LON, ELLIPSOID)
+%   [x, y] = CASSINI_FWD(lat0, lon0, lat, lon)
+%   [x, y, azi, rk] = CASSINI_FWD(lat0, lon0, lat, lon, ellipsoid)
 %
-%   performs the forward Cassini-Soldner projection of points (LAT,LON) to
-%   (X,Y) using (LAT0,LON0) as the center of projection.  These input
-%   arguments can be scalars or arrays of equal size.  The ELLIPSOID vector
+%   performs the forward Cassini-Soldner projection of points (lat,lon) to
+%   (x,y) using (lat0,lon0) as the center of projection.  These input
+%   arguments can be scalars or arrays of equal size.  The ellipsoid vector
 %   is of the form [a, e], where a is the equatorial radius in meters, e is
 %   the eccentricity.  If ellipsoid is omitted, the WGS84 ellipsoid (more
-%   precisely, the value returned by DEFAULTELLIPSOID) is used.  GEODPROJ
+%   precisely, the value returned by defaultellipsoid) is used.  geodproj
 %   defines the projection and gives the restrictions on the allowed ranges
-%   of the arguments.  The inverse projection is given by CASSINI_INV.
+%   of the arguments.  The inverse projection is given by cassini_inv.
 %
-%   AZI and RK give metric properties of the projection at (LAT,LON); AZI
-%   is the azimuth of the easting (X) direction and RK is the reciprocal of
-%   the northing (Y) scale.  The scale in the easting direction is 1.
+%   azi and rk give metric properties of the projection at (lat,lon); azi
+%   is the azimuth of the easting (x) direction and rk is the reciprocal of
+%   the northing (y) scale.  The scale in the easting direction is 1.
 %
-%   LAT0, LON0, LAT, LON, AZI are in degrees.  The projected coordinates X,
-%   Y are in meters (more precisely the units used for the equatorial
-%   radius).  RK is dimensionless.
-%
-%   This routine depends on the MATLAB File Exchange package "Geodesics on
-%   an ellipsoid of revolution":
-%
-%     http://www.mathworks.com/matlabcentral/fileexchange/39108
+%   lat0, lon0, lat, lon, azi are in degrees.  The projected coordinates x,
+%   y are in meters (more precisely the units used for the equatorial
+%   radius).  rk is dimensionless.
 %
 %   See also GEODPROJ, CASSINI_INV, GEODDISTANCE, DEFAULTELLIPSOID.
 
-% Copyright (c) Charles Karney (2012) <charles at karney.com>.
+% Copyright (c) Charles Karney (2012-2015) <charles at karney.com>.
 %
-% This file was distributed with GeographicLib 1.29.
+% This file was distributed with GeographicLib 1.42.
 
-  if nargin < 4, error('Too few input arguments'), end
+  narginchk(4, 5)
   if nargin < 5, ellipsoid = defaultellipsoid; end
   try
-    Z = lat0 + lon0 + lat + lon;
-    Z = zeros(size(Z));
-  catch err
+    Z = zeros(size(lat0 + lon0 + lat + lon));
+  catch
     error('lat0, lon0, lat, lon have incompatible sizes')
   end
   if length(ellipsoid(:)) ~= 2
@@ -72,8 +66,8 @@ function [x, y, azi, rk] = cassini_fwd(lat0, lon0, lat, lon, ellipsoid)
   azi = AngNormalize(azi2);
   [~, ~, ~, ~, ~, ~, rk] = ...
       geodreckon(lat, dlon, -sig12, azi, ellipsoid, true);
-  [sbet , cbet ] = SinCosNorm((1-f) * sind(lat ), cosd(lat ));
-  [sbet0, cbet0] = SinCosNorm((1-f) * sind(lat0), cosd(lat0));
+  [sbet , cbet ] = norm2((1-f) * sind(lat ), cosd(lat ));
+  [sbet0, cbet0] = norm2((1-f) * sind(lat0), cosd(lat0));
   alp = azi * degree;
   salp = sin(alp); salp(alp == -180) = 0;
   calp = cos(alp); calp(abs(alp) == 90) = 0;
diff --git a/matlab/geographiclib/cassini_inv.m b/matlab/geographiclib/cassini_inv.m
new file mode 100644
index 0000000..ecb35e3
--- /dev/null
+++ b/matlab/geographiclib/cassini_inv.m
@@ -0,0 +1,41 @@
+function [lat, lon, azi, rk] = cassini_inv(lat0, lon0, x, y, ellipsoid)
+%CASSINI_INV  Inverse Cassini-Soldner projection
+%
+%   [lat, lon] = CASSINI_INV(lat0, lon0, x, y)
+%   [lat, lon, azi, rk] = CASSINI_INV(lat0, lon0, x, y, ellipsoid)
+%
+%   performs the inverse Cassini-Soldner projection of points (x,y) to
+%   (lat,lon) using (lat0,lon0) as the center of projection.  These input
+%   arguments can be scalars or arrays of equal size.  The ellipsoid vector
+%   is of the form [a, e], where a is the equatorial radius in meters, e is
+%   the eccentricity.  If ellipsoid is omitted, the WGS84 ellipsoid (more
+%   precisely, the value returned by defaultellipsoid) is used.  geodproj
+%   defines the projection and gives the restrictions on the allowed ranges
+%   of the arguments.  The forward projection is given by cassini_fwd.
+%
+%   azi and rk give metric properties of the projection at (lat,lon); azi
+%   is the azimuth of the easting (x) direction and rk is the reciprocal of
+%   the northing (y) scale.  The scale in the easting direction is 1.
+%
+%   lat0, lon0, lat, lon, azi are in degrees.  The projected coordinates x,
+%   y are in meters (more precisely the units used for the equatorial
+%   radius).  rk is dimensionless.
+%
+%   See also GEODPROJ, CASSINI_FWD, GEODRECKON, DEFAULTELLIPSOID.
+
+% Copyright (c) Charles Karney (2012-2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  narginchk(4, 5)
+  if nargin < 5, ellipsoid = defaultellipsoid; end
+  try
+    [~] = lat0 + lon0 + x + y;
+  catch
+    error('lat0, lon0, x, y have incompatible sizes')
+  end
+
+  [lat1, lon1, azi0] = geodreckon(lat0, lon0, y, 0, ellipsoid);
+  [lat, lon, azi, ~, ~, rk] = ...
+      geodreckon(lat1, lon1, x, azi0 + 90, ellipsoid);
+end
diff --git a/matlab/defaultellipsoid.m b/matlab/geographiclib/defaultellipsoid.m
similarity index 76%
rename from matlab/defaultellipsoid.m
rename to matlab/geographiclib/defaultellipsoid.m
index 4b71da6..8ff072b 100644
--- a/matlab/defaultellipsoid.m
+++ b/matlab/geographiclib/defaultellipsoid.m
@@ -1,10 +1,10 @@
 function ellipsoid = defaultellipsoid
 %DEFAULTELLIPSOID  Return the WGS84 ellipsoid
 %
-%   ELLIPSOID = DEFAULTELLIPSOID
+%   ellipsoid = DEFAULTELLIPSOID
 %
 %   returns a vector of the equatorial radius and eccentricity for the
-%   WGS84 ellipsoid.  Use ECC2FLAT and FLAT2ECC to convert between
+%   WGS84 ellipsoid.  use ecc2flat and flat2ecc to convert between
 %   the eccentricity and the flattening.
 %
 %   See also ECC2FLAT, FLAT2ECC.
diff --git a/matlab/geographiclib/ecc2flat.m b/matlab/geographiclib/ecc2flat.m
new file mode 100644
index 0000000..8bdfb65
--- /dev/null
+++ b/matlab/geographiclib/ecc2flat.m
@@ -0,0 +1,12 @@
+function f = ecc2flat(e)
+%ECC2FLAT   Convert eccentricity to flattening
+%
+%   f = ECC2FLAT(e)
+%
+%   returns the flattening of an ellipsoid given the eccentricity.
+%
+%   See also FLAT2ECC.
+
+  e2 = e.^2;
+  f = e2 ./ (1 + sqrt(1 - e2));
+end
diff --git a/matlab/eqdazim_fwd.m b/matlab/geographiclib/eqdazim_fwd.m
similarity index 59%
rename from matlab/eqdazim_fwd.m
rename to matlab/geographiclib/eqdazim_fwd.m
index d934ffb..257daab 100644
--- a/matlab/eqdazim_fwd.m
+++ b/matlab/geographiclib/eqdazim_fwd.m
@@ -1,27 +1,27 @@
 function [x, y, azi, rk] = eqdazim_fwd(lat0, lon0, lat, lon, ellipsoid)
 %EQDAZIM_FWD  Forward azimuthal equidistant projection
 %
-%   [X, Y] = EQDAZIM_FWD(LAT0, LON0, LAT, LON)
-%   [X, Y, AZI, RK] = EQDAZIM_FWD(LAT0, LON0, LAT, LON, ELLIPSOID)
+%   [x, y] = EQDAZIM_FWD(lat0, lon0, lat, lon)
+%   [x, y, azi, rk] = EQDAZIM_FWD(lat0, lon0, lat, lon, ellipsoid)
 %
 %   performs the forward azimuthal equidistant projection of points
-%   (LAT,LON) to (X,Y) using (LAT0,LON0) as the center of projection.
+%   (lat,lon) to (x,y) using (lat0,lon0) as the center of projection.
 %   These input arguments can be scalars or arrays of equal size.  The
-%   ELLIPSOID vector is of the form [a, e], where a is the equatorial
+%   ellipsoid vector is of the form [a, e], where a is the equatorial
 %   radius in meters, e is the eccentricity.  If ellipsoid is omitted, the
 %   WGS84 ellipsoid (more precisely, the value returned by
-%   DEFAULTELLIPSOID) is used.  GEODPROJ defines the projection and gives
+%   defaultellipsoid) is used.  geodproj defines the projection and gives
 %   the restrictions on the allowed ranges of the arguments.  The inverse
-%   projection is given by EQDAZIM_INV.
+%   projection is given by eqdazim_inv.
 %
-%   AZI and RK give metric properties of the projection at (LAT,LON); AZI
-%   is the azimuth of the geodesic from the center of projection and RK is
+%   azi and rk give metric properties of the projection at (lat,lon); azi
+%   is the azimuth of the geodesic from the center of projection and rk is
 %   the reciprocal of the azimuthal scale.  The scale in the radial
 %   direction is 1.
 %
-%   LAT0, LON0, LAT, LON, AZI are in degrees.  The projected coordinates X,
-%   Y are in meters (more precisely the units used for the equatorial
-%   radius).  RK is dimensionless.
+%   lat0, lon0, lat, lon, azi are in degrees.  The projected coordinates x,
+%   y are in meters (more precisely the units used for the equatorial
+%   radius).  rk is dimensionless.
 %
 %   Section 14 of
 %
@@ -32,22 +32,17 @@ function [x, y, azi, rk] = eqdazim_fwd(lat0, lon0, lat, lon, ellipsoid)
 %   describes how to use this projection in the determination of maritime
 %   boundaries (finding the median line).
 %
-%   This routine depends on the MATLAB File Exchange package "Geodesics on
-%   an ellipsoid of revolution":
-%
-%     http://www.mathworks.com/matlabcentral/fileexchange/39108
-%
 %   See also GEODPROJ, EQDAZIM_INV, GEODDISTANCE, DEFAULTELLIPSOID.
 
-% Copyright (c) Charles Karney (2012) <charles at karney.com>.
+% Copyright (c) Charles Karney (2012-2015) <charles at karney.com>.
 %
-% This file was distributed with GeographicLib 1.29.
+% This file was distributed with GeographicLib 1.42.
 
-  if nargin < 4, error('Too few input arguments'), end
+  narginchk(4, 5)
   if nargin < 5, ellipsoid = defaultellipsoid; end
   try
     [~] = lat0 + lon0 + lat + lon;
-  catch err
+  catch
     error('lat0, lon0, lat, lon have incompatible sizes')
   end
 
diff --git a/matlab/eqdazim_inv.m b/matlab/geographiclib/eqdazim_inv.m
similarity index 58%
rename from matlab/eqdazim_inv.m
rename to matlab/geographiclib/eqdazim_inv.m
index 98d5981..03f779d 100644
--- a/matlab/eqdazim_inv.m
+++ b/matlab/geographiclib/eqdazim_inv.m
@@ -1,27 +1,27 @@
 function [lat, lon, azi, rk] = eqdazim_inv(lat0, lon0, x, y, ellipsoid)
 %EQDAZIM_INV  Inverse azimuthal equidistant projection
 %
-%   [LAT, LON] = EQDAZIM_INV(LAT0, LON0, X, Y)
-%   [LAT, LON, AZI, RK] = EQDAZIM_INV(LAT0, LON0, X, Y, ELLIPSOID)
+%   [lat, lon] = EQDAZIM_INV(lat0, lon0, x, y)
+%   [lat, lon, azi, rk] = EQDAZIM_INV(lat0, lon0, x, y, ellipsoid)
 %
-%   performs the inverse azimuthal equidistant projection of points (X,Y)
-%   to (LAT,LON) using (LAT0,LON0) as the center of projection.  These
-%   input arguments can be scalars or arrays of equal size.  The ELLIPSOID
+%   performs the inverse azimuthal equidistant projection of points (x,y)
+%   to (lat,lon) using (lat0,lon0) as the center of projection.  These
+%   input arguments can be scalars or arrays of equal size.  The ellipsoid
 %   vector is of the form [a, e], where a is the equatorial radius in
 %   meters, e is the eccentricity.  If ellipsoid is omitted, the WGS84
-%   ellipsoid (more precisely, the value returned by DEFAULTELLIPSOID) is
-%   used.  GEODPROJ defines the projection and gives the restrictions on
+%   ellipsoid (more precisely, the value returned by defaultellipsoid) is
+%   used.  geodproj defines the projection and gives the restrictions on
 %   the allowed ranges of the arguments.  The forward projection is given
-%   by EQDAZIM_FWD.
+%   by eqdazim_fwd.
 %
-%   AZI and RK give metric properties of the projection at (LAT,LON); AZI
-%   is the azimuth of the geodesic from the center of projection and RK is
+%   azi and rk give metric properties of the projection at (lat,lon); azi
+%   is the azimuth of the geodesic from the center of projection and rk is
 %   the reciprocal of the azimuthal scale.  The scale in the radial
 %   direction is 1.
 %
-%   LAT0, LON0, LAT, LON, AZI are in degrees.  The projected coordinates X,
-%   Y are in meters (more precisely the units used for the equatorial
-%   radius).  RK is dimensionless.
+%   lat0, lon0, lat, lon, azi are in degrees.  The projected coordinates x,
+%   y are in meters (more precisely the units used for the equatorial
+%   radius).  rk is dimensionless.
 %
 %   Section 14 of
 %
@@ -32,22 +32,17 @@ function [lat, lon, azi, rk] = eqdazim_inv(lat0, lon0, x, y, ellipsoid)
 %   describes how to use this projection in the determination of maritime
 %   boundaries (finding the median line).
 %
-%   This routine depends on the MATLAB File Exchange package "Geodesics on
-%   an ellipsoid of revolution":
-%
-%     http://www.mathworks.com/matlabcentral/fileexchange/39108
-%
 %   See also GEODPROJ, EQDAZIM_FWD, GEODRECKON, DEFAULTELLIPSOID.
 
-% Copyright (c) Charles Karney (2012) <charles at karney.com>.
+% Copyright (c) Charles Karney (2012-2015) <charles at karney.com>.
 %
-% This file was distributed with GeographicLib 1.29.
+% This file was distributed with GeographicLib 1.42.
 
-  if nargin < 4, error('Too few input arguments'), end
+  narginchk(4, 5)
   if nargin < 5, ellipsoid = defaultellipsoid; end
   try
     [~] = lat0 + lon0 + x + y;
-  catch err
+  catch
     error('lat0, lon0, x, y have incompatible sizes')
   end
 
diff --git a/matlab/geographiclib/flat2ecc.m b/matlab/geographiclib/flat2ecc.m
new file mode 100644
index 0000000..2119f68
--- /dev/null
+++ b/matlab/geographiclib/flat2ecc.m
@@ -0,0 +1,11 @@
+function e = flat2ecc(f)
+%FLAT2ECC   Convert flattening to eccentricity
+%
+%   e = FLAT2ECC(f)
+%
+%   returns the eccentricity of an ellipsoid given the flattening.
+%
+%   See also ECC2FLAT.
+
+  e = sqrt(f .* (2 - f));
+end
diff --git a/matlab/gedistance.m b/matlab/geographiclib/gedistance.m
similarity index 74%
rename from matlab/gedistance.m
rename to matlab/geographiclib/gedistance.m
index 765c118..551b893 100644
--- a/matlab/gedistance.m
+++ b/matlab/geographiclib/gedistance.m
@@ -1,5 +1,5 @@
 function [s12, azi1, azi2, S12] = gedistance(lat1, lon1, lat2, lon2, ellipsoid)
-%GEDISTANCE  Great ellipse distance between points on an ellipsoid
+%GEDISTANCE  Great ellipse distance on an ellipsoid
 %
 %   [s12, azi1, azi2] = GEDISTANCE(lat1, lon1, lat2, lon2)
 %   [s12, azi1, azi2, S12] = GEDISTANCE(lat1, lon1, lat2, lon2, ellipsoid)
@@ -11,48 +11,38 @@ function [s12, azi1, azi2, S12] = gedistance(lat1, lon1, lat2, lon2, ellipsoid)
 %   degrees.  The ellipsoid vector is of the form [a, e], where a is the
 %   equatorial radius in meters, e is the eccentricity.  If ellipsoid is
 %   omitted, the WGS84 ellipsoid (more precisely, the value returned by
-%   DEFAULTELLIPSOID) is used.  The output s12 is the distance in meters
+%   defaultellipsoid) is used.  The output s12 is the distance in meters
 %   and azi1 and azi2 are the forward azimuths at the end points in
 %   degrees.  The optional output S12 is the area between the great ellipse
-%   and the equator (in meters^2).  GEDOC gives an example and provides
-%   additional background information.  GEDOC also gives the restrictions
+%   and the equator (in meters^2).  gedoc gives an example and provides
+%   additional background information.  gedoc also gives the restrictions
 %   on the allowed ranges of the arguments.
 %
 %   When given a combination of scalar and array inputs, the scalar inputs
 %   are automatically expanded to match the size of the arrays.
 %
-%   GEODDISTANCE solves the equivalent geodesic problem and usually this is
+%   geoddistance solves the equivalent geodesic problem and usually this is
 %   preferable to using GEDISTANCE.
 %
-%   This routine depends on the MATLAB File Exchange package "Geodesics on
-%   an ellipsoid of revolution":
-%
-%     http://www.mathworks.com/matlabcentral/fileexchange/39108
-%
-%   This routine should be installed in the SAME DIRECTORY as package
-%   39108.
-%
-%   See also GEDOC, GERECKON, DEFAULTELLIPSOID, ECC2FLAT, FLAT2ECC,
-%     GEODDISTANCE, GEODRECKON.
+%   See also GEDOC, GERECKON, DEFAULTELLIPSOID, GEODDISTANCE, GEODRECKON.
 
-% Copyright (c) Charles Karney (2014) <charles at karney.com>.
+% Copyright (c) Charles Karney (2014-2015) <charles at karney.com>.
 %
-% This file was distributed with GeographicLib 1.39.
+% This file was distributed with GeographicLib 1.42.
 
-  if nargin < 4, error('Too few input arguments'), end
+  narginchk(4, 5)
   if nargin < 5, ellipsoid = defaultellipsoid; end
   try
-    Z = lat1 + lon1 + lat2 + lon2;
-    S = size(Z);
-    Z = zeros(S);
-    lat1 = lat1 + Z; lon1 = lon1 + Z;
-    lat2 = lat2 + Z; lon2 = lon2 + Z;
-  catch err
+    S = size(lat1 + lon1 + lat2 + lon2);
+  catch
     error('lat1, lon1, s12, azi1 have incompatible sizes')
   end
   if length(ellipsoid(:)) ~= 2
     error('ellipsoid must be a vector of size 2')
   end
+  Z = zeros(S);
+  lat1 = lat1 + Z; lon1 = lon1 + Z;
+  lat2 = lat2 + Z; lon2 = lon2 + Z;
 
   degree = pi/180;
   tiny = sqrt(realmin);
@@ -70,11 +60,11 @@ function [s12, azi1, azi2, S12] = gedistance(lat1, lon1, lat2, lon2, ellipsoid)
 
   phi = lat1 * degree;
   sbet1 = f1 * sin(phi); cbet1 = cos(phi); cbet1(lat1 == -90) = tiny;
-  [sbet1, cbet1] = SinCosNorm(sbet1, cbet1);
+  [sbet1, cbet1] = norm2(sbet1, cbet1);
 
   phi = lat2 * degree;
   sbet2 = f1 * sin(phi); cbet2 = cos(phi); cbet2(abs(lat2) == 90) = tiny;
-  [sbet2, cbet2] = SinCosNorm(sbet2, cbet2);
+  [sbet2, cbet2] = norm2(sbet2, cbet2);
 
   lam12 = lon12 * degree;
   slam12 = sin(lam12); slam12(lon12 == 180) = 0; clam12 = cos(lam12);
@@ -84,14 +74,14 @@ function [s12, azi1, azi2, S12] = gedistance(lat1, lon1, lat2, lon2, ellipsoid)
   sgam2 = cbet1 .* slam12; cgam2 = -sbet1 .* cbet2 + cbet1 .* sbet2 .* clam12;
   ssig12 = hypot(sgam1, cgam1);
   csig12 = sbet1 .* sbet2 + cbet1 .* cbet2 .* clam12;
-  [sgam1, cgam1] = SinCosNorm(sgam1, cgam1);
-  [sgam2, cgam2] = SinCosNorm(sgam2, cgam2);
+  [sgam1, cgam1] = norm2(sgam1, cgam1);
+  [sgam2, cgam2] = norm2(sgam2, cgam2);
   % no need to normalize [ssig12, csig12]
 
   cgam0 = hypot(cgam1, sgam1 .* sbet1);
 
   ssig1 = sbet1; csig1 = cbet1 .* cgam1;
-  [ssig1, csig1] = SinCosNorm(ssig1, csig1);
+  [ssig1, csig1] = norm2(ssig1, csig1);
   ssig2 = ssig1 .* csig12 + csig1 .* ssig12;
   csig2 = csig1 .* csig12 - ssig1 .* ssig12;
 
@@ -131,7 +121,11 @@ function [s12, azi1, azi2, S12] = gedistance(lat1, lon1, lat2, lon2, ellipsoid)
         2 * atan2(slam12(l) .* (sbet1(l) .* dbet2 + sbet2(l) .* dbet1), ...
                   dlam12    .* (sbet1(l) .* sbet2(l) + dbet1 .* dbet2));
 
-    c2 = a^2 * (1 + (1 - e2) * atanhee(1, e2)) / 2;
+    if e2 ~= 0
+      c2 = a^2 * (1 + (1 - e2) * eatanhe(1, e2) / e2) / 2;
+    else
+      c2 = a^2;
+    end
     S12 = S12 + c2 * gam12;
     S12 = reshape(S12, S);
   end
diff --git a/matlab/gedoc.m b/matlab/geographiclib/gedoc.m
similarity index 71%
rename from matlab/gedoc.m
rename to matlab/geographiclib/gedoc.m
index 1c5df18..ca4245c 100644
--- a/matlab/gedoc.m
+++ b/matlab/geographiclib/gedoc.m
@@ -1,16 +1,16 @@
 function gedoc
 %GEDOC  Great ellipses on an ellipsoid of revolution
 %
-%   This package includes two routines GEDISTANCE and GERECKON which solve
-%   the inverse and direct problems for great ellipses on the surface of an
-%   ellipsoid of revolution.  For more information, see
+%   The two routines GEDISTANCE and GERECKON solve the inverse and direct
+%   problems for great ellipses on the surface of an ellipsoid of
+%   revolution.  For more information, see
 %
 %     http://geographiclib.sf.net/html/greatellipse.html
 %
 %   Great ellipses are sometimes proposed as alternatives to computing
 %   ellipsoidal geodesics.  However geodesic calculations are easy to
-%   perform using GEODDISTANCE and GEODRECKON, and these should normally be
-%   used instead of GEDISTANCE and GERECKON.  For a discussion, see
+%   perform using geoddistance and geodreckon, and these should normally be
+%   used instead of gedistance and gereckon.  For a discussion, see
 %
 %     http://geographiclib.sf.net/html/greatellipse.html#gevsgeodesic
 %
@@ -21,17 +21,6 @@ function gedoc
 %
 %     http://geographiclib.sf.net/html/greatellipse.html#geformulation
 %
-%   Finding the distance involves computing the arc length of an ellipse
-%   and this package uses the rapidly converging series employed by MATLAB
-%   File Exchange package "Geodesics on an ellipsoid of revolution" (which
-%   provides GEODDISTANCE and GEODRECKON):
-%
-%     http://www.mathworks.com/matlabcentral/fileexchange/39108
-%
-%   gedistance.m and gereckon.m should be installed in the SAME DIRECTORY
-%   as package 39108 because these routines require access to its private
-%   utility routines.
-%
 %   Consider two points on the ellipsoid at (lat1, lon1) and (lat2, lon2).
 %   The plane containing these points and the center of the ellipsoid
 %   intersects the ellipsoid on a great ellipse.  The length of the shorter
@@ -41,9 +30,9 @@ function gedoc
 %
 %   Two great ellipse problems can be considered:
 %     * the direct problem -- given lat1, lon1, s12, and azi1, determine
-%       lat2, lon2, and azi2.  This is solved by GERECKON.
+%       lat2, lon2, and azi2.  This is solved by gereckon.
 %     * the inverse problem -- given lat1, lon1, lat2, lon2, determine s12,
-%       azi1, and azi2.  This is solved by GEDISTANCE.
+%       azi1, and azi2.  This is solved by gedistance.
 %
 %   The routines also optionally calculate S12 ,the area between the great
 %   ellipse from point 1 to point 2 and the equator; i.e., it is the area,
@@ -51,21 +40,21 @@ function gedoc
 %   (lat1,lon1), (0,lon1), (0,lon2), and (lat2,lon2).  It is given in
 %   meters^2.
 %
-%   The parameters of the ellipsoid are specified by the optional ELLIPSOID
+%   The parameters of the ellipsoid are specified by the optional ellipsoid
 %   argument to the routines.  This is a two-element vector of the form
 %   [a,e], where a is the equatorial radius, e is the eccentricity e =
 %   sqrt(a^2-b^2)/a, and b is the polar semi-axis.  Typically, a and b are
 %   measured in meters and the distances returned by the routines are then
-%   in meters.  However, other units can be employed.  If ELLIPSOID is
+%   in meters.  However, other units can be employed.  If ellipsoid is
 %   omitted, then the WGS84 ellipsoid (more precisely, the value returned
-%   by DEFAULTELLIPSOID) is assumed [6378137, 0.0818191908426215]
+%   by defaultellipsoid) is assumed [6378137, 0.0818191908426215]
 %   corresponding to a = 6378137 meters and a flattening f = (a-b)/a =
 %   1/298.257223563.  The flattening and eccentricity are related by
 %
 %       e = sqrt(f * (2 - f))
 %       f = e^2 / (1 + sqrt(1 - e^2))
 %
-%   (The functions ECC2FLAT and FLAT2ECC implement these conversions.)  For
+%   (The functions ecc2flat and flat2ecc implement these conversions.)  For
 %   a sphere, set e = 0; for a prolate ellipsoid (b > a), specify e as a
 %   pure imaginary number.
 %
@@ -81,26 +70,26 @@ function gedoc
 %       these quantities lie in [-180, 180).  It is however possible to
 %       prevent this normalization of the longitude in geodreckon by
 %       setting the long_nowrap bit in the optional flags argument.
-%     * The distance s12 is unrestricted.  This allows great ellipses to wrap
-%       around the ellipsoid.
+%     * The distance s12 is unrestricted.  This allows great ellipses to
+%       wrap around the ellipsoid.
 %     * The equatorial radius, a, must be positive.
 %     * The eccentricity, e, should be satisfy abs(e) < 0.2 in order to
 %       retain full accuracy (this corresponds to flattenings satisfying
 %       abs(f) <= 1/50, approximately).  This condition holds for most
 %       applications in geodesy.
 %
-%    Larger values of e can be used with a corresponding drop in accuracy.
-%    The following table gives the approximate maximum error in GEDISTANCE
-%    and GERECKON (expressed as a distance) for an ellipsoid with the same
-%    major radius as the WGS84 ellipsoid and different values of the
-%    flattening (nm means nanometer and um means micrometer).
+%   Larger values of e can be used with a corresponding drop in accuracy.
+%   The following table gives the approximate maximum error in gedistance
+%   and gereckon (expressed as a distance) for an ellipsoid with the same
+%   major radius as the WGS84 ellipsoid and different values of the
+%   flattening (nm means nanometer and um means micrometer).
 %
-%         |f|     error
-%         0.01    25 nm
-%         0.02    30 nm
-%         0.05    10 um
-%         0.1    1.5 mm
-%         0.2    300 mm
+%        |f|     error
+%        0.01    25 nm
+%        0.02    30 nm
+%        0.05    10 um
+%        0.1    1.5 mm
+%        0.2    300 mm
 %
 %   In order to compute intermediate points on a great ellipse, proceed as
 %   in the following example which plots the track from Sydney to
@@ -124,14 +113,14 @@ function gedoc
 %   The restriction on e above arises because the meridian distance is
 %   given as a series expansion in the third flattening.  The exact
 %   distance (valid for any e) can be expressed in terms of the elliptic
-%   integral of the second kind .
+%   integral of the second kind.
 %
 %   See also GEDISTANCE, GERECKON, DEFAULTELLIPSOID, ECC2FLAT, FLAT2ECC,
 %     GEODDISTANCE, GEODRECKON.
 
-% Copyright (c) Charles Karney (2014) <charles at karney.com>.
+% Copyright (c) Charles Karney (2014-2015) <charles at karney.com>.
 %
-% This file was distributed with GeographicLib 1.39.
+% This file was distributed with GeographicLib 1.42.
 
   help gedoc
 end
diff --git a/matlab/geographiclib/geocent_fwd.m b/matlab/geographiclib/geocent_fwd.m
new file mode 100644
index 0000000..d0b8d23
--- /dev/null
+++ b/matlab/geographiclib/geocent_fwd.m
@@ -0,0 +1,61 @@
+function [X, Y, Z, M] = geocent_fwd(lat, lon, h, ellipsoid)
+%GEOCENT_FWD  Conversion from geographic to geocentric coordinates
+%
+%   [X, Y, Z] = GEOCENT_FWD(lat, lon)
+%   [X, Y, Z] = GEOCENT_FWD(lat, lon, h)
+%   [X, Y, Z, M] = GEOCENT_FWD(lat, lon, h, ellipsoid)
+%
+%   converts from geographic coordinates, lat, lon, h to geocentric
+%   coordinates X, Y, Z.  lat, lon, h can be scalars or arrays of equal
+%   size.  lat and lon are in degrees.  h (default 0) and X, Y, Z are in
+%   meters.  The ellipsoid vector is of the form [a, e], where a is the
+%   equatorial radius in meters, e is the eccentricity.  If ellipsoid is
+%   omitted, the WGS84 ellipsoid (more precisely, the value returned by
+%   defaultellipsoid) is used.
+%
+%   M is the 3 x 3 rotation matrix for the conversion.  Pre-multiplying a
+%   unit vector in local cartesian coordinates (east, north, up) by M
+%   transforms the vector to geocentric coordinates.
+%
+%   See also GEOCENT_INV, DEFAULTELLIPSOID.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  narginchk(2, 4)
+  if nargin < 3, h = 0; end
+  if nargin < 4, ellipsoid = defaultellipsoid; end
+  try
+    z = zeros(size(lat + lon + h));
+  catch
+    error('lat, lon, h have incompatible sizes')
+  end
+  if length(ellipsoid(:)) ~= 2
+    error('ellipsoid must be a vector of size 2')
+  end
+  lat = lat + z; lon = lon + z; h = h + z;
+
+  degree = pi/180;
+  a = ellipsoid(1);
+  e2 = ellipsoid(2)^2;
+  e2m = 1 - e2;
+
+  lon = AngNormalize(lon);
+
+  phi = lat * degree;
+  lam = lon * degree;
+  sphi = sin(phi);
+  cphi = cos(phi); cphi(abs(lat) == 90) = 0;
+  n = a./sqrt(1 - e2 * sphi.^2);
+  slam = sin(lam); slam(lon == -180) = 0;
+  clam = cos(lam); clam(abs(lon) == 90) = 0;
+  Z = (e2m * n + h) .* sphi;
+  X = (n + h) .* cphi;
+  Y = X .* slam;
+  X = X .* clam;
+
+  if nargout > 3
+    M = GeoRotation(sphi, cphi, slam, clam);
+  end
+end
diff --git a/matlab/geographiclib/geocent_inv.m b/matlab/geographiclib/geocent_inv.m
new file mode 100644
index 0000000..bb82961
--- /dev/null
+++ b/matlab/geographiclib/geocent_inv.m
@@ -0,0 +1,151 @@
+function [lat, lon, h, M] = geocent_inv(X, Y, Z, ellipsoid)
+%GEOCENT_INV  Conversion from geocentric to geographic coordinates
+%
+%   [lat, lon, h] = GEOCENT_INV(X, Y, Z)
+%   [lat, lon, h, M] = GEOCENT_INV(X, Y, Z, ellipsoid)
+%
+%   converts from geocentric coordinates X, Y, Z to geographic coordinates,
+%   lat, lon, h.  X, Y, Z can be scalars or arrays of equal size.  X, Y, Z,
+%   and h are in meters.  lat and lon are in degrees.  The ellipsoid vector
+%   is of the form [a, e], where a is the equatorial radius in meters, e is
+%   the eccentricity.  If ellipsoid is omitted, the WGS84 ellipsoid (more
+%   precisely, the value returned by defaultellipsoid) is used.
+%
+%   M is the 3 x 3 rotation matrix for the conversion.  Pre-multiplying a
+%   unit vector in geocentric coordinates by the transpose of M transforms
+%   the vector to local cartesian coordinates (east, north, up).
+%
+%   See also GEOCENT_FWD, DEFAULTELLIPSOID.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  narginchk(3, 4)
+  if nargin < 4, ellipsoid = defaultellipsoid; end
+  try
+    z = zeros(size(X + Y + Z));
+  catch
+    error('X, Y, Z have incompatible sizes')
+  end
+  if length(ellipsoid(:)) ~= 2
+    error('ellipsoid must be a vector of size 2')
+  end
+  X = X + z; Y = Y + z; Z = Z + z;
+
+  degree = pi/180;
+  a = ellipsoid(1);
+  e2 = ellipsoid(2)^2;
+  e2m = 1 - e2;
+  e2a = abs(e2);
+  e4a = e2^2;
+  maxrad = 2 * a / eps;
+
+  R = hypot(X, Y);
+  slam = Y ./ R; slam(R == 0) = 0;
+  clam = X ./ R; clam(R == 0) = 1;
+  h = hypot(R, Z);
+
+  if e4a == 0
+    % Treat the spherical case.  Dealing with underflow in the general case
+    % with e2 = 0 is difficult.  Origin maps to N pole same as with
+    % ellipsoid.
+    Z1 = Z;
+    Z1(h == 0) = 1;
+    [sphi, cphi] = norm2(Z1, R);
+    h = h - a;
+  else
+    % Treat prolate spheroids by swapping R and Z here and by switching
+    % the arguments to phi = atan2(...) at the end.
+    p = (R / a).^2;
+    q = e2m * (Z / a).^2;
+    r = (p + q - e4a) / 6;
+    if e2 < 0
+      [p, q] = swap(p, q);
+    end
+
+    % Avoid possible division by zero when r = 0 by multiplying
+    % equations for s and t by r^3 and r, resp.
+    S = e4a * p .* q / 4; % S = r^3 * s
+    r2 = r.^2;
+    r3 = r .* r2;
+    disc = S .* (2 * r3 + S);
+    u = r;
+    fl2 = disc >= 0;
+    T3 = S(fl2) + r3(fl2);
+    % Pick the sign on the sqrt to maximize abs(T3).  This minimizes
+    % loss of precision due to cancellation.  The result is unchanged
+    % because of the way the T is used in definition of u.
+    % T3 = (r * t)^3
+    T3 = T3 + (1 - 2 * (T3 < 0)) .* sqrt(disc(fl2));
+    % N.B. cbrtx always returns the real root.  cbrtx(-8) = -2.
+    T = cbrtx(T3);
+    u(fl2) = u(fl2) + T + cvmgt(r2(fl2) ./ T, 0, T ~= 0);
+    % T is complex, but the way u is defined the result is real.
+    ang = atan2(sqrt(-disc(~fl2)), -(S(~fl2) + r3(~fl2)));
+    % There are three possible cube roots.  We choose the root which
+    % avoids cancellation (disc < 0 implies that r < 0).
+    u(~fl2) = u(~fl2) + 2 * r(~fl2) .* cos(ang / 3);
+    % guaranteed positive
+    v = sqrt(u.^2 + e4a * q);
+    % Avoid loss of accuracy when u < 0.  Underflow doesn't occur in
+    % e4 * q / (v - u) because u ~ e^4 when q is small and u < 0.
+    % u+v, guaranteed positive
+    uv = u + v;
+    fl2 = u < 0;
+    uv(fl2) = e4a * q(fl2) ./ (v(fl2) - u(fl2));
+    % Need to guard against w going negative due to roundoff in uv - q.
+    w = max(0, e2a * (uv - q) ./ (2 * v));
+    k = uv ./ (sqrt(uv + w.^2) + w);
+    if e2 >= 0
+      k1 = k; k2 = k + e2;
+    else
+      k1 = k - e2; k2 = k;
+    end
+    [sphi, cphi] = norm2(Z ./ k1, R ./ k2);
+    h = (1 - e2m ./ k1) .* hypot(k1 .* R ./ k2, Z);
+    % Deal with exceptional inputs
+    c = e4a * q == 0 & r <= 0;
+    if any(c)
+      % This leads to k = 0 (oblate, equatorial plane) and k + e^2 = 0
+      % (prolate, rotation axis) and the generation of 0/0 in the general
+      % formulas for phi and h.  using the general formula and division by 0
+      % in formula for h.  So handle this case by taking the limits:
+      % f > 0: z -> 0, k      ->   e2 * sqrt(q)/sqrt(e4 - p)
+      % f < 0: R -> 0, k + e2 -> - e2 * sqrt(q)/sqrt(e4 - p)
+      zz = e4a - p(c); xx = p(c);
+      if e2 < 0
+        [zz, xx] = swap(zz, xx);
+      end
+      zz = sqrt(zz / e2m);
+      xx = sqrt(xx);
+      H = hypot(zz, xx); sphi(c) = zz ./ H; cphi(c) = xx ./ H;
+      sphi(c & Z < 0) = - sphi(c & Z < 0);
+      h(c) = - a *  H / e2a;
+      if e2 >= 0
+        h(c) = e2m * h(c);
+      end
+    end
+  end
+  far = h > maxrad;
+  if any(far)
+    % We really far away (> 12 million light years); treat the earth as a
+    % point and h, above, is an acceptable approximation to the height.
+    % This avoids overflow, e.g., in the computation of disc below.  It's
+    % possible that h has overflowed to inf; but that's OK.
+    %
+    % Treat the case X, Y finite, but R overflows to +inf by scaling by 2.
+    R(far) = hypot(X(far)/2, Y(far)/2);
+    slam(far) = Y(far) ./ R(far); slam(far & R == 0) = 0;
+    clam(far) = X(far) ./ R(far); clam(far & R == 0) = 1;
+    H = hypot(Z(far)/2, R(far));
+    sphi(far) = Z(far)/2 ./ H;
+    cphi(far) = R(far) ./ H;
+  end
+  lat = atan2(sphi, cphi) / degree;
+  % Negative signs return lon in [-180, 180).  0- converts -0 to +0.
+  lon = 0 - atan2(-slam, clam) / degree;
+  if nargout > 3
+    M = GeoRotation(sphi, cphi, slam, clam);
+  end
+end
diff --git a/matlab/geodarea.m b/matlab/geographiclib/geodarea.m
similarity index 88%
rename from matlab/geodarea.m
rename to matlab/geographiclib/geodarea.m
index f0f7244..3e57647 100644
--- a/matlab/geodarea.m
+++ b/matlab/geographiclib/geodarea.m
@@ -8,7 +8,7 @@ function [A, P, N] = geodarea(lats, lons, ellipsoid)
 %   input vectors lats, lons (in degrees).  The ellipsoid vector is of the
 %   form [a, e], where a is the equatorial radius in meters, e is the
 %   eccentricity.  If ellipsoid is omitted, the WGS84 ellipsoid (more
-%   precisely, the value returned by DEFAULTELLIPSOID) is used.  There is
+%   precisely, the value returned by defaultellipsoid) is used.  There is
 %   no need to "close" the polygon by repeating the first point.  Multiple
 %   polygons can be specified by separating the vertices by NaNs in the
 %   vectors.  Thus a series of quadrilaterals can be specified as two 5 x K
@@ -19,7 +19,7 @@ function [A, P, N] = geodarea(lats, lons, ellipsoid)
 %   numbers of vertices in N.  GEODDOC gives the restrictions on the
 %   allowed ranges of the arguments.
 %
-%   GEODAREA loosely duplicates the functionality of the AREAINT function
+%   GEODAREA loosely duplicates the functionality of the areaint function
 %   in the MATLAB mapping toolbox.  The major difference is that the
 %   polygon edges are taken to be geodesics and the area contributed by
 %   each edge is computed using a series expansion with is accurate
@@ -33,11 +33,11 @@ function [A, P, N] = geodarea(lats, lons, ellipsoid)
 %   See also GEODDOC, GEODDISTANCE, GEODRECKON, POLYGONAREA,
 %     DEFAULTELLIPSOID.
 
-% Copyright (c) Charles Karney (2012-2013) <charles at karney.com>.
+% Copyright (c) Charles Karney (2012-2015) <charles at karney.com>.
 %
-% This file was distributed with GeographicLib 1.31.
+% This file was distributed with GeographicLib 1.42.
 
-  if nargin < 2, error('Too few input arguments'), end
+  narginchk(2, 3)
   if nargin < 3, ellipsoid = defaultellipsoid; end
   if ~isequal(size(lats), size(lons))
     error('lats, lons have incompatible sizes')
@@ -68,7 +68,11 @@ function [A, P, N] = geodarea(lats, lons, ellipsoid)
   f = e2 / (1 + sqrt(1 - e2));
 
   b = (1 - f) * a;
-  c2 = (a^2 + b^2 * atanhee(1, e2)) / 2;
+  if e2 ~= 0
+    c2 = (a^2 + b^2 * eatanhe(1, e2) / e2) / 2;
+  else
+    c2 = a^2;
+  end
   area0 = 4 * pi * c2;
 
   [s12, ~, ~, S12] = geoddistance(lat1, lon1, lat2, lon2, ellipsoid);
@@ -79,14 +83,14 @@ function [A, P, N] = geodarea(lats, lons, ellipsoid)
     P(k) = accumulator(s12(m0(k):m1(k)));
     [As, At] = accumulator(S12(m0(k):m1(k)));
     crossings = sum(cross(m0(k):m1(k)));
-    if mod(crossings, 2) ~= 0,
+    if mod(crossings, 2) ~= 0
       [As, At] = accumulator( ((As < 0) * 2 - 1) * area0 / 2, As, At);
     end
     As = -As; At = -At;
     if As > area0/2
-      As = accumulator( -area0 / 2, As, At);
+      As = accumulator(-area0, As, At);
     elseif As <= -area0/2
-      As = accumulator(  area0 / 2, As, At);
+      As = accumulator( area0, As, At);
     end
     A(k) = As;
   end
@@ -116,7 +120,7 @@ function [s, t] = accumulator(x, s, t)
   if nargin < 3, t = 0; end
   if nargin < 2, s = 0; end
 
-  for y = x(:)',
+  for y = x(:)'
     % Here's Shewchuk's solution...
     [z, u] = sumx(y, t);
     [s, t] = sumx(z, s);
diff --git a/matlab/geoddistance.m b/matlab/geographiclib/geoddistance.m
similarity index 94%
rename from matlab/geoddistance.m
rename to matlab/geographiclib/geoddistance.m
index 708de81..284f693 100644
--- a/matlab/geoddistance.m
+++ b/matlab/geographiclib/geoddistance.m
@@ -13,10 +13,10 @@ function [s12, azi1, azi2, S12, m12, M12, M21, a12] = geoddistance ...
 %   The ellipsoid vector is of the form [a, e], where a is the equatorial
 %   radius in meters, e is the eccentricity.  If ellipsoid is omitted, the
 %   WGS84 ellipsoid (more precisely, the value returned by
-%   DEFAULTELLIPSOID) is used.  The output s12 is the distance in meters
+%   defaultellipsoid) is used.  The output s12 is the distance in meters
 %   and azi1 and azi2 are the forward azimuths at the end points in
 %   degrees.  The other optional outputs, S12, m12, M12, M21, a12 are
-%   documented in GEODDOC.  GEODDOC also gives the restrictions on the
+%   documented in geoddoc.  geoddoc also gives the restrictions on the
 %   allowed ranges of the arguments.
 %
 %   When given a combination of scalar and array inputs, the scalar inputs
@@ -29,7 +29,7 @@ function [s12, azi1, azi2, S12, m12, M12, M21, a12] = geoddistance ...
 %     https://dx.doi.org/10.1007/s00190-012-0578-z
 %     Addenda: http://geographiclib.sf.net/geod-addenda.html
 %
-%   This function duplicates some of the functionality of the DISTANCE
+%   This function duplicates some of the functionality of the distance
 %   function in the MATLAB mapping toolbox.  Differences are
 %
 %     * When the ellipsoid argument is omitted, use the WGS84 ellipsoid.
@@ -42,9 +42,9 @@ function [s12, azi1, azi2, S12, m12, M12, M21, a12] = geoddistance ...
 %   See also GEODDOC, GEODRECKON, GEODAREA, GEODESICINVERSE,
 %     DEFAULTELLIPSOID.
 
-% Copyright (c) Charles Karney (2012, 2013) <charles at karney.com>.
+% Copyright (c) Charles Karney (2012-2015) <charles at karney.com>.
 %
-% This file was distributed with GeographicLib 1.31.
+% This file was distributed with GeographicLib 1.42.
 %
 % This is a straightforward transcription of the C++ implementation in
 % GeographicLib and the C++ source should be consulted for additional
@@ -53,21 +53,20 @@ function [s12, azi1, azi2, S12, m12, M12, M21, a12] = geoddistance ...
 % with scalar arguments.  The biggest change was to eliminate the branching
 % to allow a vectorized solution.
 
-  if nargin < 4, error('Too few input arguments'), end
+  narginchk(4, 5)
   if nargin < 5, ellipsoid = defaultellipsoid; end
   try
-    Z = lat1 + lon1 + lat2 + lon2;
-    S = size(Z);
-    Z = zeros(S);
-    lat1 = lat1 + Z; lon1 = lon1 + Z;
-    lat2 = lat2 + Z; lon2 = lon2 + Z;
-    Z = Z(:);
-  catch err
+    S = size(lat1 + lon1 + lat2 + lon2);
+  catch
     error('lat1, lon1, s12, azi1 have incompatible sizes')
   end
   if length(ellipsoid(:)) ~= 2
     error('ellipsoid must be a vector of size 2')
   end
+  Z = zeros(S);
+  lat1 = lat1 + Z; lon1 = lon1 + Z;
+  lat2 = lat2 + Z; lon2 = lon2 + Z;
+  Z = Z(:);
 
   degree = pi/180;
   tiny = sqrt(realmin);
@@ -107,11 +106,11 @@ function [s12, azi1, azi2, S12, m12, M12, M21, a12] = geoddistance ...
 
   phi = lat1 * degree;
   sbet1 = f1 * sin(phi); cbet1 = cos(phi); cbet1(lat1 == -90) = tiny;
-  [sbet1, cbet1] = SinCosNorm(sbet1, cbet1);
+  [sbet1, cbet1] = norm2(sbet1, cbet1);
 
   phi = lat2 * degree;
   sbet2 = f1 * sin(phi); cbet2 = cos(phi); cbet2(abs(lat2) == 90) = tiny;
-  [sbet2, cbet2] = SinCosNorm(sbet2, cbet2);
+  [sbet2, cbet2] = norm2(sbet2, cbet2);
 
   c = cbet1 < -sbet1 & cbet2 == cbet1;
   sbet2(c) = (2 * (sbet2(c) < 0) - 1) .* sbet1(c);
@@ -222,7 +221,7 @@ function [s12, azi1, azi2, S12, m12, M12, M21, a12] = geoddistance ...
 
     salp1(c) = (salp1a(c) + salp1b(c))/2;
     calp1(c) = (calp1a(c) + calp1b(c))/2;
-    [salp1(g), calp1(g)] = SinCosNorm(salp1(g), calp1(g));
+    [salp1(g), calp1(g)] = norm2(salp1(g), calp1(g));
     tripb(c) = (abs(salp1a(c) - salp1(c)) + (calp1a(c) - calp1(c)) < tolb | ...
                 abs(salp1(c) - salp1b(c)) + (calp1(c) - calp1b(c)) < tolb);
   end
@@ -246,8 +245,8 @@ function [s12, azi1, azi2, S12, m12, M12, M21, a12] = geoddistance ...
     k2 = calp0.^2 * ep2;
     epsi = k2 ./ (2 * (1 + sqrt(1 + k2)) + k2);
     A4 = (a^2 * e2) * calp0 .* salp0;
-    [ssig1, csig1] = SinCosNorm(ssig1, csig1);
-    [ssig2, csig2] = SinCosNorm(ssig2, csig2);
+    [ssig1, csig1] = norm2(ssig1, csig1);
+    [ssig2, csig2] = norm2(ssig2, csig2);
 
     C4x = C4coeff(n);
     C4a = C4f(epsi, C4x);
@@ -268,7 +267,11 @@ function [s12, azi1, azi2, S12, m12, M12, M21, a12] = geoddistance ...
     s = salp12 == 0 & calp12 < 0;
     salp12(s) = tiny * calp1(s); calp12(s) = -1;
     alp12(l) = atan2(salp12, calp12);
-    c2 = (a^2 + b^2 * atanhee(1, e2)) / 2;
+    if e2 ~= 0
+      c2 = (a^2 + b^2 * eatanhe(1, e2) / e2) / 2;
+    else
+      c2 = a^2;
+    end
     S12 = 0 + swapp .* lonsign .* latsign .* (S12 + c2 * alp12);
   end
 
@@ -334,7 +337,7 @@ function [sig12, salp1, calp1, salp2, calp2, dnm] = ...
   calp2(s) = somg12(s).^2 ./ (1 + comg12(s));
   calp2(s & comg12 < 0) = 1 - comg12(s & comg12 < 0);
   calp2(s) = sbet12(s) - cbet1(s) .* sbet2(s) .* calp2(s);
-  [salp2, calp2] = SinCosNorm(salp2, calp2);
+  [salp2, calp2] = norm2(salp2, calp2);
   sig12(s) = atan2(ssig12(s), csig12(s));
 
   s = ~(s | abs(n) > 0.1 | csig12 >= 0 | ssig12 >= 6 * abs(n) * pi * cbet1.^2);
@@ -385,7 +388,7 @@ function [sig12, salp1, calp1, salp2, calp2, dnm] = ...
   end
 
   calp1(salp1 <= 0) = 0; salp1(salp1 <= 0) = 1;
-  [salp1, calp1] = SinCosNorm(salp1, calp1);
+  [salp1, calp1] = norm2(salp1, calp1);
 end
 
 function k = Astroid(x, y)
@@ -414,7 +417,7 @@ function k = Astroid(x, y)
   fl2 = disc >= 0;
   T3 = S(fl2) + r3(fl2);
   T3 = T3 + (1 - 2 * (T3 < 0)) .* sqrt(disc(fl2));
-  T = cbrt(T3);
+  T = cbrtx(T3);
   u(fl2) = u(fl2) + T + cvmgt(r2(fl2) ./ T, 0, T ~= 0);
   ang = atan2(sqrt(-disc(~fl2)), -(S(~fl2) + r3(~fl2)));
   u(~fl2) = u(~fl2) + 2 * r(~fl2) .* cos(ang / 3);
@@ -443,7 +446,7 @@ function [lam12, dlam12, ...
 
   ssig1 = sbet1; somg1 = salp0 .* sbet1;
   csig1 = calp1 .* cbet1; comg1 = csig1;
-  [ssig1, csig1] = SinCosNorm(ssig1, csig1);
+  [ssig1, csig1] = norm2(ssig1, csig1);
 
   salp2 = cvmgt(salp0 ./ cbet2, salp1, cbet2 ~= cbet1);
   calp2 = cvmgt(sqrt((calp1 .* cbet1).^2 + ...
@@ -453,7 +456,7 @@ function [lam12, dlam12, ...
                 abs(calp1), cbet2 ~= cbet1 | abs(sbet2) ~= -sbet1);
   ssig2 = sbet2; somg2 = salp0 .* sbet2;
   csig2 = calp2 .* cbet2;  comg2 = csig2;
-  [ssig2, csig2] = SinCosNorm(ssig2, csig2);
+  [ssig2, csig2] = norm2(ssig2, csig2);
 
   sig12 = atan2(max(csig1 .* ssig2 - ssig1 .* csig2, 0), ...
                 csig1 .* csig2 + ssig1 .* ssig2);
diff --git a/matlab/geoddoc.m b/matlab/geographiclib/geoddoc.m
similarity index 78%
rename from matlab/geoddoc.m
rename to matlab/geographiclib/geoddoc.m
index ea886b5..478f338 100644
--- a/matlab/geoddoc.m
+++ b/matlab/geographiclib/geoddoc.m
@@ -1,9 +1,9 @@
 function geoddoc
 %GEODDOC  Geodesics on an ellipsoid of revolution
 %
-%   This package includes three routines GEODDISTANCE, GEODRECKON, and
-%   GEODAREA which solve various problems involving geodesics on the
-%   surface of an ellipsoid of revolution.  These are based on the paper
+%   The routines geoddistance, geodreckon, and geodarea solve various
+%   problems involving geodesics on the surface of an ellipsoid of
+%   revolution.  These are based on the paper
 %
 %     C. F. F. Karney, Algorithms for geodesics,
 %     J. Geodesy 87, 43-55 (2013);
@@ -24,20 +24,20 @@ function geoddoc
 %
 %   Traditionally two geodesic problems are considered:
 %     * the direct problem -- given lat1, lon1, s12, and azi1, determine
-%       lat2, lon2, and azi2.  This is solved by GEODRECKON.
+%       lat2, lon2, and azi2.  This is solved by geodreckon.
 %     * the inverse problem -- given lat1, lon1, lat2, lon2, determine s12,
-%       azi1, and azi2.  This is solved by GEODDISTANCE.
-%   In addition, GEODAREA computes the area of an ellipsoidal polygon
+%       azi1, and azi2.  This is solved by geoddistance.
+%   In addition, geodarea computes the area of an ellipsoidal polygon
 %   where the edges are defined as shortest geodesics.
 %
-%   The parameters of the ellipsoid are specified by the optional ELLIPSOID
+%   The parameters of the ellipsoid are specified by the optional ellipsoid
 %   argument to the routines.  This is a two-element vector of the form
 %   [a,e], where a is the equatorial radius, e is the eccentricity e =
 %   sqrt(a^2-b^2)/a, and b is the polar semi-axis.  Typically, a and b are
 %   measured in meters and the linear and area quantities returned by the
 %   routines are then in meters and meters^2.  However, other units can be
 %   employed.  If ELLIPSOID is omitted, then the WGS84 ellipsoid (more
-%   precisely, the value returned by DEFAULTELLIPSOID) is assumed [6378137,
+%   precisely, the value returned by defaultellipsoid) is assumed [6378137,
 %   0.0818191908426215] corresponding to a = 6378137 meters and a
 %   flattening f = (a-b)/a = 1/298.257223563.  The flattening and
 %   eccentricity are related by
@@ -45,7 +45,7 @@ function geoddoc
 %       e = sqrt(f * (2 - f))
 %       f = e^2 / (1 + sqrt(1 - e^2))
 %
-%   (The functions ECC2FLAT and FLAT2ECC implement these conversions.)  For
+%   (The functions ecc2flat and flat2ecc implement these conversions.)  For
 %   a sphere, set e = 0; for a prolate ellipsoid (b > a), specify e as a
 %   pure imaginary number.
 %
@@ -103,7 +103,7 @@ function geoddoc
 %
 %    Larger values of e can be used with a corresponding drop in accuracy.
 %    The following table gives the approximate maximum error in
-%    GEODDISTANCE and GEODRECKON (expressed as a distance) for an ellipsoid
+%    geoddistance and geodreckon (expressed as a distance) for an ellipsoid
 %    with the same major radius as the WGS84 ellipsoid and different values
 %    of the flattening (nm means nanometer and um means micrometer).
 %
@@ -146,53 +146,31 @@ function geoddoc
 %       [lats, lons] = geodreckon(lat1, lon1, s12 * [0:100]/100, azi1);
 %       plot(lons, lats);
 %
-%   These routines are transcriptions of the C++ classes, Geodesic,
-%   GeodesicLine, and PolygonArea, provided by GeographicLib which is
-%   available at
-%
-%     http://geographiclib.sf.net
-%
-%   An alternate MATLAB interface is provided by the wrapper functions,
-%   GEODESICDIRECT, GEODESICLINE, GEODESICINVERSE, and POLYGONAREA which
-%   are part of GeographicLib.  However these depend on being able to
-%   compile and link the interface code, which limits their usefulness.
-%   GEODDISTANCE, GEODRECKON, and GEODAREA are native implementations which
-%   will work on any MATLAB platform.  They are fully vectorized so that
-%   their speed is competitive with the compiled C++ code.  Implementations
-%   of these routines in Python and JavaScript are also available; see
-%
-%     http://geographiclib.sf.net/html/other.html
-%
 %   The restriction on e above arises because the formulation is in terms
 %   of series expansions in e^2.  The exact solutions (valid for any e) can
 %   be expressed in terms of elliptic integrals.  These are provided by the
 %   C++ classes GeodesicExact and GeodesicLineExact.
 %
-%   The routines duplicate some of the functionality of the DISTANCE,
-%   RECKON, and AREAINT functions in the MATLAB mapping toolbox.  The major
-%   improvements offered by GEODDISTANCE, GEODRECKON, and GEODAREA are
+%   The routines duplicate some of the functionality of the distance,
+%   reckon, and areaint functions in the MATLAB mapping toolbox.  The major
+%   improvements offered by geoddistance, geodreckon, and geodarea are
 %
 %     * The routines are accurate to round off for abs(e) < 0.2.  For
 %       example, for the WGS84 ellipsoid, the error in the distance
-%       returned by GEODDISTANCE is less then 15 nanometers.
+%       returned by geoddistance is less then 15 nanometers.
 %     * The routines work for prolate (as well as oblate) ellipsoids.
-%     * GEODDISTANCE converges for all inputs.
+%     * geoddistance converges for all inputs.
 %     * Differential and integral properties of the geodesics are computed.
-%     * GEODAREA is accurate regardless of the length of the edges of the
+%     * geodarea is accurate regardless of the length of the edges of the
 %       polygon.
 %
-%   This package is used by the MATLAB File Exchange package "Geodesic
-%   projections for an ellipsoid":
-%
-%     http://www.mathworks.com/matlabcentral/fileexchange/39366
-%
 %   See also GEODDISTANCE, GEODRECKON, GEODAREA,
 %     DEFAULTELLIPSOID, ECC2FLAT, FLAT2ECC,
 %     GEODESICDIRECT, GEODESICLINE, GEODESICINVERSE, POLYGONAREA.
 
-% Copyright (c) Charles Karney (2012-2014) <charles at karney.com>.
+% Copyright (c) Charles Karney (2012-2015) <charles at karney.com>.
 %
-% This file was distributed with GeographicLib 1.39.
+% This file was distributed with GeographicLib 1.42.
 
   help geoddoc
 end
diff --git a/matlab/geodreckon.m b/matlab/geographiclib/geodreckon.m
similarity index 94%
rename from matlab/geodreckon.m
rename to matlab/geographiclib/geodreckon.m
index 6e027de..e30470f 100644
--- a/matlab/geodreckon.m
+++ b/matlab/geographiclib/geodreckon.m
@@ -12,10 +12,10 @@ function [lat2, lon2, azi2, S12, m12, M12, M21, a12_s12] = geodreckon ...
 %   azi1 are given in degrees and s12 in meters.  The ellipsoid vector is
 %   of the form [a, e], where a is the equatorial radius in meters, e is
 %   the eccentricity.  If ellipsoid is omitted, the WGS84 ellipsoid (more
-%   precisely, the value returned by DEFAULTELLIPSOID) is used.  lat2,
+%   precisely, the value returned by defaultellipsoid) is used.  lat2,
 %   lon2, and azi2 give the position and forward azimuths at the end point
 %   in degrees.  The other outputs, S12, m12, M12, M21, a12 are documented
-%   in GEODDOC.  GEODDOC also gives the restrictions on the allowed ranges
+%   in geoddoc.  geoddoc also gives the restrictions on the allowed ranges
 %   of the arguments.
 %
 %   flags (default 0) is a combination of 2 flags:
@@ -69,9 +69,9 @@ function [lat2, lon2, azi2, S12, m12, M12, M21, a12_s12] = geodreckon ...
 %   See also GEODDOC, GEODDISTANCE, GEODAREA, GEODESICDIRECT, GEODESICLINE,
 %     DEFAULTELLIPSOID.
 
-% Copyright (c) Charles Karney (2012-2014) <charles at karney.com>.
+% Copyright (c) Charles Karney (2012-2015) <charles at karney.com>.
 %
-% This file was distributed with GeographicLib 1.39.
+% This file was distributed with GeographicLib 1.42.
 %
 % This is a straightforward transcription of the C++ implementation in
 % GeographicLib and the C++ source should be consulted for additional
@@ -79,10 +79,10 @@ function [lat2, lon2, azi2, S12, m12, M12, M21, a12_s12] = geodreckon ...
 % with array arguments are identical to those obtained with multiple calls
 % with scalar arguments.
 
-  if nargin < 4, error('Too few input arguments'), end
+  narginchk(4, 6)
   try
     S = size(lat1 + lon1 + s12_a12 + azi1);
-  catch err
+  catch
     error('lat1, lon1, s12, azi1 have incompatible sizes')
   end
   if nargin <= 4
@@ -141,13 +141,13 @@ function [lat2, lon2, azi2, S12, m12, M12, M21, a12_s12] = geodreckon ...
   phi = lat1 * degree;
   sbet1 = f1 * sin(phi);
   cbet1 = cos(phi); cbet1(abs(lat1) == 90) = tiny;
-  [sbet1, cbet1] = SinCosNorm(sbet1, cbet1);
+  [sbet1, cbet1] = norm2(sbet1, cbet1);
   dn1 = sqrt(1 + ep2 * sbet1.^2);
 
   salp0 = salp1 .* cbet1; calp0 = hypot(calp1, salp1 .* sbet1);
   ssig1 = sbet1; somg1 = salp0 .* sbet1;
   csig1 = cbet1 .* calp1; csig1(sbet1 == 0 & calp1 == 0) = 1; comg1 = csig1;
-  [ssig1, csig1] = SinCosNorm(ssig1, csig1);
+  [ssig1, csig1] = norm2(ssig1, csig1);
 
   k2 = calp0.^2 * ep2;
   epsi = k2 ./ (2 * (1 + sqrt(1 + k2)) + k2);
@@ -173,7 +173,7 @@ function [lat2, lon2, azi2, S12, m12, M12, M21, a12_s12] = geodreckon ...
   else
     tau12 = s12_a12 ./ (b * (1 + A1m1));
     s = sin(tau12); c = cos(tau12);
-    B12 = - SinCosSeries(true,  stau1 .* c + ctau1 .* s, ...
+    B12 = - SinCosSeries(true, stau1 .* c + ctau1 .* s, ...
                          ctau1 .* c - stau1 .* s, C1pa);
     sig12 = tau12 - (B12 - B11);
     ssig12 = sin(sig12); csig12 = cos(sig12);
@@ -262,7 +262,11 @@ function [lat2, lon2, azi2, S12, m12, M12, M21, a12_s12] = geodreckon ...
     calp12(s) = calp2(s) .* calp1(s) + salp2(s) .* salp1(s);
     s = s & salp12 == 0 & calp12 < 0;
     salp12(s) = tiny * calp1(s); calp12(s) = -1;
-    c2 = (a^2 + b^2 * atanhee(1, e2)) / 2;
+    if e2 ~= 0
+      c2 = (a^2 + b^2 * eatanhe(1, e2) / e2) / 2;
+    else
+      c2 = a^2;
+    end
     S12 = c2 * atan2(salp12, calp12) + A4 .* (B42 - B41);
   end
 
diff --git a/matlab/geographiclib/geoid_height.m b/matlab/geographiclib/geoid_height.m
new file mode 100644
index 0000000..10d5b86
--- /dev/null
+++ b/matlab/geographiclib/geoid_height.m
@@ -0,0 +1,165 @@
+function h = geoid_height(lat, lon, geoidname, geoiddir)
+%GEOID_HEIGHT  Compute the height of the geoid
+%
+%   height = GEOID_HEIGHT(lat, lon)
+%   height = GEOID_HEIGHT(lat, lon, geoidname)
+%   height = GEOID_HEIGHT(lat, lon, geoidname, geoiddir)
+%            GEOID_HEIGHT([])
+%   height = GEOID_HEIGHT(lat, lon, geoid)
+%
+%   computes the height of the geoid in meters.  lat and lon are the
+%   latitude and longitude in degrees.  These can be scalars or arrays of
+%   the same size.  The possible geoids are
+%
+%       egm84-30  egm84-15
+%       egm96-15  egm96-5
+%       egm2008-5 egm2008-2_5 egm2008-1
+%
+%   The first part of the name is the geoid model.  The second part gives
+%   the resolution of the gridded data (in arc-seconds).
+%
+%   By default the egm96-5 geoid is used.  This can be overridden by
+%   specifying geoidname.  The geoiddir argument overrides the default
+%   directory for the model.  See the documentation on geoid_load for how
+%   these arguments are interpreted.
+%
+%   When geoid_height is invoked with a particular geoidname, the geoid
+%   data is loaded from disk and cached.  A subsequent invocation of
+%   geoid_height with the same geoidname uses the cached data.  Use
+%   GEOID_HEIGHT([]) to clear this cached data.
+%
+%   Alternatively, you can load a geoid with geoid_load and use the
+%   returned structure as the third argument.  This use does not change the
+%   cached data.
+%
+%   In order to use this routine with Octave, Octave needs to have been
+%   compiled with a version of GraphicsMagick which supports 16-bit images.
+%   Also, the first time you uses this routine, you may receive a warning
+%   message "your version of GraphicsMagick limits images to 16 bits per
+%   pixel"; this can safely be ignored.
+%
+%   Information on downloading and installing the data for the supported
+%   geoid models is available at
+%
+%     http://geographiclib.sf.net/html/geoid.html#geoidinst
+%
+%   GEOID_HEIGHT uses cubic interpolation on gridded data that has been
+%   quantized at a resolution of 3mm.
+%
+%   See also GEOID_LOAD.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  persistent saved_geoid
+  if nargin == 1 && isempty(lat)
+    saved_geoid = [];
+    return
+  end
+  narginchk(2, 4)
+  if nargin == 3 && isstruct(geoidname)
+    h = geoid_height_int(lat, lon, geoidname);
+  else
+    if nargin < 3
+      geoidname = '';
+    end
+    if nargin < 4
+      geoiddir = '';
+    end
+    geoidfile = geoid_file(geoidname, geoiddir);
+    if ~(isstruct(saved_geoid) && strcmp(saved_geoid.file, geoidfile))
+      saved_geoid = geoid_load_file(geoidfile);
+    end
+    h = geoid_height_int(lat, lon, saved_geoid);
+  end
+end
+
+function height = geoid_height_int(lat, lon, geoid, cubic)
+  if nargin < 4, cubic = true; end
+  try
+    s = size(lat + lon);
+  catch
+    error('lat, lon have incompatible sizes')
+  end
+  num = prod(s); Z = zeros(num,1);
+  lat = lat(:) + Z; lon = lon(:) + Z;
+  h = geoid.h; w = geoid.w;
+  % lat is in [0, h]
+  flat = min(max((90 - lat) * (h - 1) / 180, 0), (h - 1));
+  % lon is in [0, w)
+  flon = mod(lon * w / 360, w);
+  flon(isnan(flon)) = 0;
+  ilat = min(floor(flat), h - 2);
+  ilon = floor(flon);
+  flat = flat - ilat; flon = flon - ilon;
+  if ~cubic
+    ind = imgind(ilon + [0,0,1,1], ilat + [0,1,0,1], w, h);
+    hf = double(geoid.im(ind));
+    height = (1 - flon) .* ((1 - flat) .* hf(:,1) + flat .* hf(:,2)) + ...
+             flon       .* ((1 - flat) .* hf(:,3) + flat .* hf(:,4));
+  else
+    ind = imgind(repmat(ilon, 1, 12) + ...
+                 repmat([ 0, 1,-1, 0, 1, 2,-1, 0, 1, 2, 0, 1], num, 1), ...
+                 repmat(ilat, 1, 12) + ...
+                 repmat([-1,-1, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2], num, 1), ...
+                 w, h);
+    hf = double(geoid.im(ind));
+    c0 = 240;
+    c3 = [ 9, -18, -88,    0,  96,   90,   0,   0, -60, -20;...
+          -9,  18,   8,    0, -96,   30,   0,   0,  60, -20;...
+           9, -88, -18,   90,  96,    0, -20, -60,   0,   0;...
+         186, -42, -42, -150, -96, -150,  60,  60,  60,  60;...
+          54, 162, -78,   30, -24,  -90, -60,  60, -60,  60;...
+          -9, -32,  18,   30,  24,    0,  20, -60,   0,   0;...
+          -9,   8,  18,   30, -96,    0, -20,  60,   0,   0;...
+          54, -78, 162,  -90, -24,   30,  60, -60,  60, -60;...
+         -54,  78,  78,   90, 144,   90, -60, -60, -60, -60;...
+           9,  -8, -18,  -30, -24,    0,  20,  60,   0,   0;...
+          -9,  18, -32,    0,  24,   30,   0,   0, -60,  20;...
+           9, -18,  -8,    0, -24,  -30,   0,   0,  60,  20];
+    c0n = 372;
+    c3n = [ 0, 0, -131, 0,  138,  144, 0,   0, -102, -31;...
+            0, 0,    7, 0, -138,   42, 0,   0,  102, -31;...
+           62, 0,  -31, 0,    0,  -62, 0,   0,    0,  31;...
+          124, 0,  -62, 0,    0, -124, 0,   0,    0,  62;...
+          124, 0,  -62, 0,    0, -124, 0,   0,    0,  62;...
+           62, 0,  -31, 0,    0,  -62, 0,   0,    0,  31;...
+            0, 0,   45, 0, -183,   -9, 0,  93,   18,   0;...
+            0, 0,  216, 0,   33,   87, 0, -93,   12, -93;...
+            0, 0,  156, 0,  153,   99, 0, -93,  -12, -93;...
+            0, 0,  -45, 0,   -3,    9, 0,  93,  -18,   0;...
+            0, 0,  -55, 0,   48,   42, 0,   0,  -84,  31;...
+            0, 0,   -7, 0,  -48,  -42, 0,   0,   84,  31];
+    c0s = 372;
+    c3s = [ 18,  -36, -122,   0,  120,  135, 0,   0,  -84, -31;...
+           -18,   36,   -2,   0, -120,   51, 0,   0,   84, -31;...
+            36, -165,  -27,  93,  147,   -9, 0, -93,   18,   0;...
+           210,   45, -111, -93,  -57, -192, 0,  93,   12,  93;...
+           162,  141,  -75, -93, -129, -180, 0,  93,  -12,  93;...
+           -36,  -21,   27,  93,   39,    9, 0, -93,  -18,   0;...
+             0,    0,   62,   0,    0,   31, 0,   0,    0, -31;...
+             0,    0,  124,   0,    0,   62, 0,   0,    0, -62;...
+             0,    0,  124,   0,    0,   62, 0,   0,    0, -62;...
+             0,    0,   62,   0,    0,   31, 0,   0,    0, -31;...
+           -18,   36,  -64,   0,   66,   51, 0,   0, -102,  31;...
+            18,  -36,    2,   0,  -66,  -51, 0,   0,  102,  31];
+    hfx = hf * c3 / c0;
+    hfx(ilat ==   0,:) = hf(ilat ==   0,:) * c3n / c0n;
+    hfx(ilat == h-2,:) = hf(ilat == h-2,:) * c3s / c0s;
+    height = sum(hfx .* [Z+1, flon, flat, flon.^2, flon.*flat, flat.^2, ...
+                        flon.^3, flon.^2.*flat, flon.*flat.^2, flat.^3], ...
+                 2);
+  end
+  height = geoid.offset + geoid.scale * height;
+  height(~(abs(lat) <= 90 & abs(lon) <= 540)) = nan;
+  height = reshape(height, s);
+end
+
+function ind = imgind(ix, iy, w, h)
+% return 1-based 1d index to w*h array for 0-based 2d indices (ix,iy)
+  c = iy <  0; iy(c) =           - iy(c); ix(c) = ix(c) + w/2;
+  c = iy >= h; iy(c) = 2 * (h-1) - iy(c); ix(c) = ix(c) + w/2;
+  ix = mod(ix, w);
+  ind = 1 + iy + ix * h;
+end
diff --git a/matlab/geographiclib/geoid_load.m b/matlab/geographiclib/geoid_load.m
new file mode 100644
index 0000000..347a55b
--- /dev/null
+++ b/matlab/geographiclib/geoid_load.m
@@ -0,0 +1,53 @@
+function geoid = geoid_load(name, dir)
+%GEOID_LOAD  Load a geoid model
+%
+%   geoid = GEOID_LOAD
+%   geoid = GEOID_LOAD(geoidname)
+%   geoid = GEOID_LOAD(geoidname, geoiddir)
+%
+%   Loads geoid data into the workspace.  The possible geoids are
+%
+%       egm84-30  egm84-15
+%       egm96-15  egm96-5
+%       egm2008-5 egm2008-2_5 egm2008-1
+%
+%   The first part of the name is the geoid model.  The second part gives
+%   the resolution of the gridded data (in arc-seconds).
+%
+%   If geoidname is not specified (or is empty), the environment variable
+%   GEOGRAPHICLIB_GEOID_NAME is used; if this is not defined then egm96-5
+%   is used.  geoid_height looks in the directory geoiddir for the geoid
+%   data; if this is not specified (or is empty), it uses the environment
+%   variable GEOGRAPHICLIB_GEOID_PATH; if this is not defined, it appends
+%   "/geoids" to the environment variable GEOGRAPHICLIB_DATA; finally, if
+%   GEOGRAPHICLIB_DATA is not defined, it tries the default directory names
+%   /usr/local/share/GeographicLib/geoids (for non-Windows systems) or
+%   C:/ProgramData/GeographicLib/geoids (for Windows systems).
+%
+%   The geoid data is loaded from the image file obtained by concatenating
+%   the components to give geoiddir/geoidname.pgm.  These files store a
+%   grid of geoid height encoded as 16-bit integers.
+%
+%   The returned geoid can be passed to geoid_height to determine the
+%   height of the geoid.
+%
+%   Information on downloading and installing the data for the supported
+%   geoid models is available at
+%
+%     http://geographiclib.sf.net/html/geoid.html#geoidinst
+%
+%   See also GEOID_HEIGHT.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  if nargin < 1
+    file = geoid_file;
+  elseif nargin < 2
+    file = geoid_file(name);
+  else
+    file = geoid_file(name, dir);
+  end
+  geoid = geoid_load_file(file);
+end
diff --git a/matlab/gereckon.m b/matlab/geographiclib/gereckon.m
similarity index 83%
rename from matlab/gereckon.m
rename to matlab/geographiclib/gereckon.m
index 0272643..8376ce0 100644
--- a/matlab/gereckon.m
+++ b/matlab/geographiclib/gereckon.m
@@ -1,5 +1,5 @@
 function [lat2, lon2, azi2, S12] = gereckon(lat1, lon1, s12, azi1, ellipsoid)
-%GERECKON  Point along great ellipse at specified azimuth and range
+%GERECKON  Point along great ellipse at given azimuth and range
 %
 %   [lat2, lon2, azi2] = GERECKON(lat1, lon1, s12, azi1)
 %   [lat2, lon2, azi2, S12] = GERECKON(lat1, lon1, s12, azi1, ellipsoid)
@@ -25,29 +25,20 @@ function [lat2, lon2, azi2, S12] = gereckon(lat1, lon1, s12, azi1, ellipsoid)
 %   of points along a single geodesic is efficiently computed by specifying
 %   an array for S12 only.)
 %
-%   GEODRECKON solves the equivalent geodesic problem and usually this is
+%   geodreckon solves the equivalent geodesic problem and usually this is
 %   preferable to using GERECKON.
 %
-%   This routine depends on the MATLAB File Exchange package "Geodesics on
-%   an ellipsoid of revolution":
-%
-%     http://www.mathworks.com/matlabcentral/fileexchange/39108
-%
-%   This routine should be installed in the SAME DIRECTORY as package
-%   39108.
-%
-%   See also GEDOC, GEDISTANCE, DEFAULTELLIPSOID, ECC2FLAT, FLAT2ECC,
-%     GEODDISTANCE, GEODRECKON.
+%   See also GEDOC, GEDISTANCE, DEFAULTELLIPSOID, GEODDISTANCE, GEODRECKON.
 
-% Copyright (c) Charles Karney (2014) <charles at karney.com>.
+% Copyright (c) Charles Karney (2014-2015) <charles at karney.com>.
 %
-% This file was distributed with GeographicLib 1.39.
+% This file was distributed with GeographicLib 1.42.
 
-  if nargin < 4, error('Too few input arguments'), end
+  narginchk(4, 5)
   if nargin < 5, ellipsoid = defaultellipsoid; end
   try
     S = size(lat1 + lon1 + s12 + azi1);
-  catch err
+  catch
     error('lat1, lon1, s12, azi1 have incompatible sizes')
   end
   if length(ellipsoid) ~= 2
@@ -75,12 +66,12 @@ function [lat2, lon2, azi2, S12] = gereckon(lat1, lon1, s12, azi1, ellipsoid)
   phi = lat1 * degree;
   sbet1 = f1 * sin(phi);
   cbet1 = cos(phi); cbet1(abs(lat1) == 90) = tiny;
-  [sbet1, cbet1] = SinCosNorm(sbet1, cbet1);
-  [sgam1, cgam1] = SinCosNorm(sgam1 .* sqrt(1 - e2 * cbet1.^2), cgam1);
+  [sbet1, cbet1] = norm2(sbet1, cbet1);
+  [sgam1, cgam1] = norm2(sgam1 .* sqrt(1 - e2 * cbet1.^2), cgam1);
   sgam0 = sgam1 .* cbet1; cgam0 = hypot(cgam1, sgam1 .* sbet1);
   ssig1 = sbet1; slam1 = sgam0 .* sbet1;
   csig1 = cbet1 .* cgam1; csig1(sbet1 == 0 & cgam1 == 0) = 1; clam1 = csig1;
-  [ssig1, csig1] = SinCosNorm(ssig1, csig1);
+  [ssig1, csig1] = norm2(ssig1, csig1);
 
   k2 = e2 * cgam0.^2;
   epsi = k2 ./ (2 * (1 + sqrt(1 - k2)) - k2);
@@ -93,7 +84,7 @@ function [lat2, lon2, azi2, S12] = gereckon(lat1, lon1, s12, azi1, ellipsoid)
   C1pa = C1pf(epsi);
   tau12 = s12 ./ A1;
   s = sin(tau12); c = cos(tau12);
-  B12 = - SinCosSeries(true,  stau1 .* c + ctau1 .* s, ...
+  B12 = - SinCosSeries(true, stau1 .* c + ctau1 .* s, ...
                        ctau1 .* c - stau1 .* s, C1pa);
   sig12 = tau12 - (B12 - B11);
   ssig12 = sin(sig12); csig12 = cos(sig12);
@@ -142,7 +133,11 @@ function [lat2, lon2, azi2, S12] = gereckon(lat1, lon1, s12, azi1, ellipsoid)
     cgam12(s) = cgam2(s) .* cgam1(s) + sgam2(s) .* sgam1(s);
     s = s & sgam12 == 0 & cgam12 < 0;
     sgam12(s) = tiny * cgam1(s); cgam12(s) = -1;
-    c2 = a^2 * (1 + (1 - e2) * atanhee(1, e2)) / 2;
+    if e2 ~= 0
+      c2 = a^2 * (1 + (1 - e2) * eatanhe(1, e2) / e2) / 2;
+    else
+      c2 = a^2;
+    end
     S12 = c2 * atan2(sgam12, cgam12) + A4 .* (B42 - B41);
   end
 
diff --git a/matlab/gnomonic_fwd.m b/matlab/geographiclib/gnomonic_fwd.m
similarity index 61%
rename from matlab/gnomonic_fwd.m
rename to matlab/geographiclib/gnomonic_fwd.m
index 3608239..eef9b59 100644
--- a/matlab/gnomonic_fwd.m
+++ b/matlab/geographiclib/gnomonic_fwd.m
@@ -1,30 +1,30 @@
 function [x, y, azi, rk] = gnomonic_fwd(lat0, lon0, lat, lon, ellipsoid)
 %GNOMONIC_FWD  Forward ellipsoidal gnomonic projection
 %
-%   [X, Y] = GNOMONIC_FWD(LAT0, LON0, LAT, LON)
-%   [X, Y, AZI, RK] = GNOMONIC_FWD(LAT0, LON0, LAT, LON, ELLIPSOID)
+%   [x, y] = GNOMONIC_FWD(lat0, lon0, lat, lon)
+%   [x, y, azi, rk] = GNOMONIC_FWD(lat0, lon0, lat, lon, ellipsoid)
 %
 %   performs the forward ellipsoidal gnomonic projection of points
-%   (LAT,LON) to (X,Y) using (LAT0,LON0) as the center of projection.
+%   (lat,lon) to (x,y) using (lat0,lon0) as the center of projection.
 %   These input arguments can be scalars or arrays of equal size.  The
-%   ELLIPSOID vector is of the form [a, e], where a is the equatorial
+%   ellipsoid vector is of the form [a, e], where a is the equatorial
 %   radius in meters, e is the eccentricity.  If ellipsoid is omitted, the
 %   WGS84 ellipsoid (more precisely, the value returned by
-%   DEFAULTELLIPSOID) is used.  GEODPROJ defines the projection and gives
+%   defaultellipsoid) is used.  geodproj defines the projection and gives
 %   the restrictions on the allowed ranges of the arguments.  The inverse
-%   projection is given by GNOMONIC_INV.
+%   projection is given by gnomonic_inv.
 %
-%   AZI and RK give metric properties of the projection at (LAT,LON); AZI
-%   is the azimuth of the geodesic from the center of projection and RK is
+%   azi and rk give metric properties of the projection at (lat,lon); azi
+%   is the azimuth of the geodesic from the center of projection and rk is
 %   the reciprocal of the azimuthal scale.  The scale in the radial
-%   direction is 1/RK^2.
+%   direction is 1/rk^2.
 %
-%   If the point lies "over the horizon", i.e., if RK <= 0, then NaNs are
-%   returned for X and Y (the correct values are returned for AZI and RK).
+%   If the point lies "over the horizon", i.e., if rk <= 0, then NaNs are
+%   returned for x and y (the correct values are returned for azi and rk).
 %
-%   LAT0, LON0, LAT, LON, AZI are in degrees.  The projected coordinates X,
-%   Y are in meters (more precisely the units used for the equatorial
-%   radius).  RK is dimensionless.
+%   lat0, lon0, lat, lon, azi are in degrees.  The projected coordinates x,
+%   y are in meters (more precisely the units used for the equatorial
+%   radius).  rk is dimensionless.
 %
 %   The ellipsoidal gnomonic projection is an azimuthal projection about a
 %   center point.  All geodesics through the center point are projected
@@ -40,22 +40,17 @@ function [x, y, azi, rk] = gnomonic_fwd(lat0, lon0, lat, lon, ellipsoid)
 %   which also includes methods for solving the "intersection" and
 %   "interception" problems using the gnomonic projection.
 %
-%   This routine depends on the MATLAB File Exchange package "Geodesics on
-%   an ellipsoid of revolution":
-%
-%     http://www.mathworks.com/matlabcentral/fileexchange/39108
-%
 %   See also GEODPROJ, GNOMONIC_INV, GEODDISTANCE, DEFAULTELLIPSOID.
 
-% Copyright (c) Charles Karney (2012) <charles at karney.com>.
+% Copyright (c) Charles Karney (2012-2015) <charles at karney.com>.
 %
-% This file was distributed with GeographicLib 1.29.
+% This file was distributed with GeographicLib 1.42.
 
-  if nargin < 4, error('Too few input arguments'), end
+  narginchk(4, 5)
   if nargin < 5, ellipsoid = defaultellipsoid; end
   try
     [~] = lat0 + lon0 + lat + lon;
-  catch err
+  catch
     error('lat0, lon0, lat, lon have incompatible sizes')
   end
 
diff --git a/matlab/gnomonic_inv.m b/matlab/geographiclib/gnomonic_inv.m
similarity index 67%
rename from matlab/gnomonic_inv.m
rename to matlab/geographiclib/gnomonic_inv.m
index 9cb0e72..522b309 100644
--- a/matlab/gnomonic_inv.m
+++ b/matlab/geographiclib/gnomonic_inv.m
@@ -1,31 +1,31 @@
 function [lat, lon, azi, rk] = gnomonic_inv(lat0, lon0, x, y, ellipsoid)
 %GNOMONIC_INV  Inverse ellipsoidal gnomonic projection
 %
-%   [LAT, LON] = GNOMONIC_INV(LAT0, LON0, X, Y)
-%   [LAT, LON, AZI, RK] = GNOMONIC_INV(LAT0, LON0, X, Y, ELLIPSOID)
+%   [lat, lon] = GNOMONIC_INV(lat0, lon0, x, y)
+%   [lat, lon, azi, rk] = GNOMONIC_INV(lat0, lon0, x, y, ellipsoid)
 %
-%   performs the inverse ellipsoidal gnomonic projection of points (X,Y) to
-%   (LAT,LON) using (LAT0,LON0) as the center of projection.  These input
-%   arguments can be scalars or arrays of equal size.  The ELLIPSOID vector
+%   performs the inverse ellipsoidal gnomonic projection of points (x,y) to
+%   (lat,lon) using (lat0,lon0) as the center of projection.  These input
+%   arguments can be scalars or arrays of equal size.  The ellipsoid vector
 %   is of the form [a, e], where a is the equatorial radius in meters, e is
 %   the eccentricity.  If ellipsoid is omitted, the WGS84 ellipsoid (more
-%   precisely, the value returned by DEFAULTELLIPSOID) is used.  GEODPROJ
+%   precisely, the value returned by defaultellipsoid) is used.  geodproj
 %   defines the projection and gives the restrictions on the allowed ranges
-%   of the arguments.  The forward projection is given by GNOMONIC_FWD.
+%   of the arguments.  The forward projection is given by gnomonic_fwd.
 %
-%   AZI and RK give metric properties of the projection at (LAT,LON); AZI
-%   is the azimuth of the geodesic from the center of projection and RK is
+%   azi and rk give metric properties of the projection at (lat,lon); azi
+%   is the azimuth of the geodesic from the center of projection and rk is
 %   the reciprocal of the azimuthal scale.  The scale in the radial
-%   direction is 1/RK^2.
+%   direction is 1/rk^2.
 %
-%   In principle, all finite X and Y are allowed.  However, it's possible
-%   that the inverse projection fails for very large X and Y (when the
+%   In principle, all finite x and y are allowed.  However, it's possible
+%   that the inverse projection fails for very large x and y (when the
 %   geographic position is close to the "horizon").  In that case, NaNs are
 %   returned for the corresponding output variables.
 %
-%   LAT0, LON0, LAT, LON, AZI are in degrees.  The projected coordinates X,
-%   Y are in meters (more precisely the units used for the equatorial
-%   radius).  RK is dimensionless.
+%   lat0, lon0, lat, lon, azi are in degrees.  The projected coordinates x,
+%   y are in meters (more precisely the units used for the equatorial
+%   radius).  rk is dimensionless.
 %
 %   The ellipsoidal gnomonic projection is an azimuthal projection about a
 %   center point.  All geodesics through the center point are projected
@@ -41,23 +41,17 @@ function [lat, lon, azi, rk] = gnomonic_inv(lat0, lon0, x, y, ellipsoid)
 %   which also includes methods for solving the "intersection" and
 %   "interception" problems using the gnomonic projection.
 %
-%   This routine depends on the MATLAB File Exchange package "Geodesics on
-%   an ellipsoid of revolution":
-%
-%     http://www.mathworks.com/matlabcentral/fileexchange/39108
-%
 %   See also GEODPROJ, GNOMONIC_FWD, GEODRECKON, DEFAULTELLIPSOID.
 
-% Copyright (c) Charles Karney (2012) <charles at karney.com>.
+% Copyright (c) Charles Karney (2012-2015) <charles at karney.com>.
 %
-% This file was distributed with GeographicLib 1.29.
+% This file was distributed with GeographicLib 1.42.
 
-  if nargin < 4, error('Too few input arguments'), end
+  narginchk(4, 5)
   if nargin < 5, ellipsoid = defaultellipsoid; end
   try
-    Z = lat0 + lon0 + x + y;
-    Z = zeros(size(Z));
-  catch err
+    Z = zeros(size(lat0 + lon0 + x + y));
+  catch
     error('lat0, lon0, x, y have incompatible sizes')
   end
   if length(ellipsoid(:)) ~= 2
diff --git a/matlab/geographiclib/loccart_fwd.m b/matlab/geographiclib/loccart_fwd.m
new file mode 100644
index 0000000..0531c6b
--- /dev/null
+++ b/matlab/geographiclib/loccart_fwd.m
@@ -0,0 +1,57 @@
+function [x, y, z, M] = loccart_fwd(lat0, lon0, h0, lat, lon, h, ellipsoid)
+%LOCCART_FWD  Convert geographic to local cartesian coordinates
+%
+%   [x, y, z] = LOCCART_FWD(lat0, lon0, h0, lat, lon)
+%   [x, y, z] = LOCCART_FWD(lat0, lon0, h0, lat, lon, h)
+%   [x, y, z, M] = LOCCART_FWD(lat0, lon0, h0, lat, lon, h, ellipsoid)
+%
+%   converts from geodetic coordinates, lat, lon, h to local cartesian
+%   coordinates, x, y, z, centered at lat0, lon0, h0.  Latitudes and
+%   longitudes are in degrees; h (default 0), h0, x, y, z are in meters.
+%   lat, lon, h can be scalars or arrays of equal size.  lat0, lon0, h0
+%   must be scalars.  The ellipsoid vector is of the form [a, e], where a
+%   is the equatorial radius in meters, e is the eccentricity.  If
+%   ellipsoid is omitted, the WGS84 ellipsoid (more precisely, the value
+%   returned by defaultellipsoid) is used.
+%
+%   M is the 3 x 3 rotation matrix for the conversion.  Pre-multiplying a
+%   unit vector in local cartesian coordinates at (lat, lon, h) by M
+%   transforms the vector to local cartesian coordinates at (lat0, lon0,
+%   h0).
+%
+%   See also LOCCART_INV, DEFAULTELLIPSOID.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  narginchk(5, 7)
+  if nargin < 6, h = 0; end
+  if nargin < 7, ellipsoid = defaultellipsoid; end
+  try
+    S = size(lat + lon + h);
+  catch
+    error('lat, lon, h have incompatible sizes')
+  end
+  if ~(isscalar(lat0) && isscalar(lon0) && isscalar(h0))
+    error('lat0, lon0, h0 must be scalar')
+  end
+  if length(ellipsoid(:)) ~= 2
+    error('ellipsoid must be a vector of size 2')
+  end
+  num = prod(S);
+  Z = zeros(num, 1);
+  lat = lat(:) + Z;
+  lon = lon(:) + Z;
+  h = h(:) + Z;
+  [X0, Y0, Z0, M0] = geocent_fwd(lat0, lon0, h0, ellipsoid);
+  [X , Y , Z , M ] = geocent_fwd(lat , lon , h , ellipsoid);
+  r = [X-X0, Y-Y0, Z-Z0] * M0;
+  x = reshape(r(:, 1), S); y = reshape(r(:, 2), S); z = reshape(r(:, 3), S);
+  if nargout > 3
+    for i = 1:num
+      M(:,:, i) = M0' * M(:,:, i);
+    end
+    M = reshape(M, [3, 3, S]);
+  end
+end
diff --git a/matlab/geographiclib/loccart_inv.m b/matlab/geographiclib/loccart_inv.m
new file mode 100644
index 0000000..f57c6ff
--- /dev/null
+++ b/matlab/geographiclib/loccart_inv.m
@@ -0,0 +1,56 @@
+function [lat, lon, h, M] = loccart_inv(lat0, lon0, h0, x, y, z, ellipsoid)
+%LOCCART_INV  Convert local cartesian to geographic coordinates
+%
+%   [lat, lon, h] = LOCCART_INV(lat0, lon0, h0, x, y, z)
+%   [lat, lon, h, M] = LOCCART_INV(lat0, lon0, h0, x, y, z, ellipsoid)
+%
+%   converts from local cartesian coordinates, x, y, z, centered at lat0,
+%   lon0, h0 to geodetic coordinates, lat, lon, h.  Latitudes and
+%   longitudes are in degrees; h, h0, x, y, z are in meters.  x, y, z can
+%   be scalars or arrays of equal size.  lat0, lon0, h0 must be scalars.
+%   The ellipsoid vector is of the form [a, e], where a is the equatorial
+%   radius in meters, e is the eccentricity.  If ellipsoid is omitted, the
+%   WGS84 ellipsoid (more precisely, the value returned by
+%   defaultellipsoid) is used.
+%
+%   M is the 3 x 3 rotation matrix for the conversion.  Pre-multiplying a
+%   unit vector in local cartesian coordinates at (lat0, lon0, h0) by the
+%   transpose of M transforms the vector to local cartesian coordinates at
+%   (lat, lon, h).
+%
+%   See also LOCCART_FWD, DEFAULTELLIPSOID.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  narginchk(6, 7)
+  if nargin < 7, ellipsoid = defaultellipsoid; end
+  try
+    S = size(x + y + z);
+  catch
+    error('x, y, z have incompatible sizes')
+  end
+  if ~(isscalar(lat0) && isscalar(lon0) && isscalar(h0))
+    error('lat0, lon0, h0 must be scalar')
+  end
+  if length(ellipsoid(:)) ~= 2
+    error('ellipsoid must be a vector of size 2')
+  end
+  num = prod(S);
+  Z = zeros(num, 1);
+  x = x(:) + Z;
+  y = y(:) + Z;
+  z = z(:) + Z;
+  [X0, Y0, Z0, M0] = geocent_fwd(lat0, lon0, h0, ellipsoid);
+  r = [x, y, z] * M0';
+  X = r(:, 1) + X0; Y = r(:, 2) + Y0; Z = r(:, 3) + Z0;
+  [lat , lon , h , M] = geocent_inv(X, Y, Z, ellipsoid);
+  lat = reshape(lat, S); lon = reshape(lon, S); h = reshape(h, S);
+  if nargout > 3
+    for i = 1:num
+      M(:,:, i) = M0' * M(:,:, i);
+    end
+    M = reshape(M, [3, 3, S]);
+  end
+end
diff --git a/matlab/geographiclib/mgrs_fwd.m b/matlab/geographiclib/mgrs_fwd.m
new file mode 100644
index 0000000..376c021
--- /dev/null
+++ b/matlab/geographiclib/mgrs_fwd.m
@@ -0,0 +1,169 @@
+function mgrs = mgrs_fwd(x, y, zone, isnorth, prec)
+%MGRS_FWD  Convert UTM/UPS coordinates to MGRS
+%
+%   mgrs = MGRS_FWD(x, y, zone, isnorth)
+%   mgrs = MGRS_FWD(x, y, zone, isnorth, prec)
+%
+%   converts from the UTM/UPS system to MGRS.  (x,y) are the easting and
+%   northing (in meters); zone is the UTM zone, in [1,60], or 0 for UPS;
+%   isnorth is 1 (0) for the northern (southern) hemisphere.  prec in
+%   [-1,11] gives the precision of the grid reference; the default is 5
+%   giving 1 m precision.  prec = 0 corresponds to 100 km precision.  A
+%   value of -1 means that only the grid zone is returned.  The maximum
+%   allowed value of prec is 11 (denoting 1 um precision).  The MGRS
+%   references are returned in a cell array of strings.  x, y, zone,
+%   isnorth, prec can be scalars or arrays of the same size.  Values that
+%   can't be converted to MGRS return the "invalid" string, "INV".  The
+%   inverse operation is performed by mgrs_inv.
+%
+%   The allowed values of (x,y) are
+%        UTM: x in [100 km, 900 km]
+%             y in [0 km, 9500 km] for northern hemisphere
+%             y in [1000 km, 10000 km] for southern hemisphere
+%        UPS: x and y in [1300 km, 2700 km] for northern hemisphere
+%             x and y in [800 km, 3200 km] for southern hemisphere
+%
+%   The ranges are 100 km more restrictive than for utmups_fwd and
+%   utmups_inv.
+%
+%   See also MGRS_INV, UTMUPS_FWD.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  narginchk(4, 5)
+  if nargin < 5, prec = 5; end
+  zone = floor(zone);
+  prec = floor(prec);
+  try
+    s = size(x + y + zone + isnorth + prec);
+  catch
+    error('x, y, zone, isnorth, prec have incompatible sizes')
+  end
+  num = prod(s);
+  if num == 0, mgrs = cell(0); return, end
+  Z = zeros(num, 1);
+  x = x(:) + Z; y = y(:) + Z; zone = zone(:) + Z;
+  isnorth = isnorth(:) + Z; prec = prec(:) + Z;
+  prec(~(prec >= -1 & prec <= 11)) = -2;
+  mgrs = repmat('INV', num, 1);
+  if ~any(prec >= -1), mgrs = reshape(cellstr(mgrs), s); return, end
+  maxprec = max(prec);
+  mgrs = [mgrs, repmat(' ', num, 2 + 2*maxprec)];
+  minprec = min(prec(prec >= -1));
+  for p = minprec:maxprec
+    in = prec == p;
+    if ~any(in)
+      continue
+    end
+    t = mgrs_fwd_p(x(in), y(in), zone(in), isnorth(in), p);
+    mgrs(in,1:(5 + 2*p)) = t;
+  end
+  mgrs = reshape(cellstr(mgrs), s);
+end
+
+function mgrs = mgrs_fwd_p(x, y, zone, northp, prec)
+  num = size(x, 1);
+  delta = 10e-9;
+  mgrs = repmat('INV', num, 1);
+  mgrs = [mgrs, repmat(' ', num, 2 + 2*prec)];
+  utm = zone >= 1 & zone <= 60;
+  y(utm & ~northp) = y(utm & ~northp) - 100e5;
+  northp(utm) = 1;
+  utm = utm & x >= 1e5 & x <= 9e5 & y >= -90e5 & y <= 95e5;
+  x(utm & x ==  9e5) =  9e5 - delta;
+  y(utm & y == 95e5) = 95e5 - delta;
+  upsn = zone == 0 &  northp;
+  upss = zone == 0 & ~northp;
+  upsn = upsn & x >= 13e5 & x <= 27e5 & y >= 13e5 & y <= 27e5;
+  x(upsn & x == 27e5) = 27e5 - delta;
+  y(upsn & y == 27e5) = 27e5 - delta;
+  upss = upss & x >=  8e5 & x <= 32e5 & y >=  8e5 & y <= 32e5;
+  x(upss & x == 32e5) = 32e5 - delta;
+  y(upss & y == 32e5) = 32e5 - delta;
+  t = mgrs_fwd_utm(x(utm), y(utm), zone(utm), prec); mgrs(utm,:) = t;
+  t = mgrs_fwd_upsn(x(upsn), y(upsn), prec); mgrs(upsn,1:end-2) = t;
+  t = mgrs_fwd_upss(x(upss), y(upss), prec); mgrs(upss,1:end-2) = t;
+end
+
+function mgrs = mgrs_fwd_utm(x, y, zone, prec)
+  mgrs = char(zeros(length(x), 5 + 2 * prec) + ' ');
+  if isempty(x), return, end
+  mgrs(:,1) = '0' + floor(zone / 10);
+  mgrs(:,2) = '0' + mod(zone, 10);
+  ys = y / 1e5;
+  latp = 0.901 * ys + ((ys > 0) * 2 - 1) * 0.135;
+  late = 0.902 * ys .* (1 - 1.85e-6 * ys .* ys);
+  latp(abs(ys) < 1) = 0.9 * ys(abs(ys) < 1);
+  late(abs(ys) < 1) = latp(abs(ys) < 1);
+  band = LatitudeBand(latp);
+  bande =  LatitudeBand(late);
+  c = band ~= bande;
+  band(c) = LatitudeBand(utmups_inv(x(c), y(c), zone(c), 1));
+  latband = 'CDEFGHJKLMNPQRSTUVWX';
+  mgrs(:,3) = latband(band + 11);
+  if prec < 0, return, end
+  xh = floor(x / 1e5); yh = floor(y / 1e5);
+  utmcols = ['ABCDEFGH', 'JKLMNPQR', 'STUVWXYZ'];
+  utmrow = 'ABCDEFGHJKLMNPQRSTUV';
+  mgrs(:,4) = utmcols(mod(zone - 1, 3) * 8 + xh);
+  mgrs(:,5) = utmrow(mod(yh + mod(zone - 1, 2) * 5, 20) + 1);
+  if prec == 0, return, end
+  x = x - 1e5 * xh; y = y - 1e5 * yh;
+  xy = formatnum(x, y, prec);
+  mgrs(:,5+(1:2*prec)) = xy;
+end
+
+function mgrs = mgrs_fwd_upsn(x, y, prec)
+  mgrs = char(zeros(length(x), 3 + 2 * prec) + ' ');
+  if isempty(x), return, end
+  upsband = 'YZ';
+  xh = floor(x / 1e5);
+  eastp = xh >= 20;
+  mgrs(:,1) = upsband(eastp + 1);
+  if prec < 0, return, end
+  yh = floor(y / 1e5);
+  upscols = ['RSTUXYZ', 'ABCFGHJ'];
+  upsrow = 'ABCDEFGHJKLMNP';
+  mgrs(:,2) = upscols(eastp * 7 + xh - cvmgt(20, 13, eastp) + 1);
+  mgrs(:,3) = upsrow(yh - 13 + 1);
+  if prec == 0, return, end
+  x = x - 1e5 * xh; y = y - 1e5 * yh;
+  xy = formatnum(x, y, prec);
+  mgrs(:,3+(1:2*prec)) = xy;
+end
+
+function mgrs = mgrs_fwd_upss(x, y, prec)
+  mgrs = char(zeros(length(x), 3 + 2 * prec) + ' ');
+  if isempty(x), return, end
+  upsband = 'AB';
+  xh = floor(x / 1e5);
+  eastp = xh >= 20;
+  mgrs(:,1) = upsband(eastp + 1);
+  if prec < 0, return, end
+  yh = floor(y / 1e5);
+  upscols = ['JKLPQRSTUXYZ', 'ABCFGHJKLPQR'];
+  upsrow = 'ABCDEFGHJKLMNPQRSTUVWXYZ';
+  mgrs(:,2) = upscols(eastp * 12 + xh - cvmgt(20, 8, eastp) + 1);
+  mgrs(:,3) = upsrow(yh - 8 + 1);
+  if prec == 0, return, end
+  x = x - 1e5 * xh; y = y - 1e5 * yh;
+  xy = formatnum(x, y, prec);
+  mgrs(:,3+(1:2*prec)) = xy;
+end
+
+function xy = formatnum(x, y, prec)
+  if (prec < 5)
+    x = x / 10 ^ (5 - prec); y = y / 10 ^ (5 - prec);
+  elseif (prec > 5)
+    x = x * 10 ^ (prec - 5); y = y * 10 ^ (prec - 5);
+  end
+  xy = [num2str(floor(x), ['%0', int2str(prec), 'd']), ...
+        num2str(floor(y), ['%0', int2str(prec), 'd'])];
+end
+
+function band = LatitudeBand(lat)
+  band = max(-10, min(9, floor(lat / 8)));
+  band(~(abs(lat) <= 90)) = nan;
+end
diff --git a/matlab/geographiclib/mgrs_inv.m b/matlab/geographiclib/mgrs_inv.m
new file mode 100644
index 0000000..809a7d8
--- /dev/null
+++ b/matlab/geographiclib/mgrs_inv.m
@@ -0,0 +1,214 @@
+function [x, y, zone, isnorth, prec] = mgrs_inv(mgrs)
+%MGRS_INV  Convert MGRS to UTM/UPS coordinates
+%
+%   [x, y, zone, isnorth] = MGRS_INV(mgrs)
+%   [x, y, zone, isnorth, prec] = MGRS_INV(mgrs)
+%
+%   converts MGRS grid references to the UTM/UPS system.  mgrs is either a
+%   2d character array of MGRS grid references (optionally padded on the
+%   right with spaces) or a cell array of character strings.  (x,y) are the
+%   easting and northing (in meters); zone is the UTM zone in [1,60] or 0
+%   for UPS; isnorth is 1 (0) for the northern (southern) hemisphere.  prec
+%   is the precision of the grid reference.  For prec >= 0, the position of
+%   the center of the grid square is returned.  To obtain the SW corner
+%   subtract 0.5 * 10^(5-prec) from the easting and northing.  prec = -1
+%   means that the grid reference consists of a grid zone only; in this
+%   case some representative position in the grid zone is returned.
+%   Illegal MGRS references result in x = y = NaN, zone = -4, isnorth = 0,
+%   prec = -2.  The inverse operation is performed by mgrs_fwd.
+%
+%   See also MGRS_FWD, UTMUPS_INV.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  if ischar(mgrs)
+    mgrs = cellstr(mgrs);
+  end
+  if iscell(mgrs)
+    s = size(mgrs);
+    mgrs = char(deblank(mgrs));
+  else
+    error('mgrs must be cell array of strings or 2d char array')
+  end
+  mgrs = upper(mgrs);
+  num = size(mgrs, 1);
+  x = nan(num, 1); y = x; prec = -2 * ones(num, 1);
+  isnorth = false(num, 1); zone = 2 * prec;
+  if num == 0, return, end
+  % pad with 5 spaces so we can access letter positions without checks
+  mgrs = [mgrs, repmat(' ', num, 5)];
+  d = isstrprop(mgrs(:,1), 'digit') & ~isstrprop(mgrs(:,2), 'digit');
+  mgrs(d,2:end) = mgrs(d,1:end-1);
+  mgrs(d,1) = '0';
+  % check that spaces only at end
+  contig = sum(abs(diff(isspace(mgrs), 1, 2)), 2) <= 1;
+  utm = isstrprop(mgrs(:,1), 'digit') & contig;
+  upss = (mgrs(:,1) == 'A' | mgrs(:,1) == 'B') & contig;
+  upsn = (mgrs(:,1) == 'Y' | mgrs(:,1) == 'Z') & contig;
+  [x(utm), y(utm), zone(utm), isnorth(utm), prec(utm)] = ...
+      mgrs_inv_utm(mgrs(utm,:));
+  [x(upsn), y(upsn), zone(upsn), isnorth(upsn), prec(upsn)] = ...
+      mgrs_inv_upsn(mgrs(upsn,:));
+  [x(upss), y(upss), zone(upss), isnorth(upss), prec(upss)] = ...
+      mgrs_inv_upss(mgrs(upss,:));
+  x = reshape(x, s); y = reshape(y, s); prec = reshape(prec, s);
+  isnorth = reshape(isnorth, s); zone = reshape(zone, s);
+end
+
+function [x, y, zone, northp, prec] = mgrs_inv_utm(mgrs)
+  zone = (mgrs(:,1) - '0') * 10 + (mgrs(:,2) - '0');
+  ok = zone > 0 & zone <= 60;
+  band = lookup('CDEFGHJKLMNPQRSTUVWX', mgrs(:,3));
+  ok = ok & band >= 0;
+  band = band - 10;
+  northp = band >= 0;
+  colind = lookup(['ABCDEFGH', 'JKLMNPQR', 'STUVWXYZ'], mgrs(:, 4)) - ...
+           mod(zone - 1, 3) * 8;
+  % good values in [0,8), bad values = -1
+  colind(colind >= 8) = -1;
+  rowind = lookup('ABCDEFGHJKLMNPQRSTUV', mgrs(:, 5));
+  even = mod(zone, 2) == 0;
+  bad = rowind < 0;
+  rowind(even) = mod(rowind(even) - 5, 20);
+  % good values in [0,20), bad values = -1
+  rowind(bad) = -1;
+  [x, y, prec] = decodexy(mgrs(:, 6:end));
+  prec(mgrs(:,4) == ' ') = -1;
+  ok = ok & (prec == -1 | (colind >= 0 & rowind >= 0));
+  rowind = utmrow(band, colind, rowind);
+  colind = colind + 1;
+  x = colind * 1e5 + x;
+  y = rowind * 1e5 + y + (1-northp) * 100e5;
+  x(prec == -1) = ...
+          (5 - (zone(prec == -1) == 31 & band(prec == -1) == 7)) * 1e5;
+  y(prec == -1) = ...
+          floor(8 * (band(prec == -1) + 0.5) * 100/90 + 0.5) * 1e5 + ...
+          (1- northp(prec == -1)) * 100e5;
+  x(~ok) = nan;
+  y(~ok) = nan;
+  northp(~ok) = false;
+  zone(~ok) = -4;
+  prec(~ok) = -2;
+end
+
+function [x, y, zone, northp, prec] = mgrs_inv_upsn(mgrs)
+  zone = zeros(size(mgrs,1),1);
+  ok = zone == 0;
+  northp = ok;
+  eastp = lookup('YZ', mgrs(:,1));
+  ok = ok & eastp >= 0;
+  colind = lookup(['RSTUXYZ', 'ABCFGHJ'], mgrs(:, 2));
+  ok = ok & (colind < 0 | mod(floor(colind / 7) + eastp, 2) == 0);
+  rowind = lookup('ABCDEFGHJKLMNP', mgrs(:, 3));
+  [x, y, prec] = decodexy(mgrs(:, 4:end));
+  prec(mgrs(:,2) == ' ') = -1;
+  ok = ok & (prec == -1 | (colind >= 0 & rowind >= 0));
+  x = (colind + 13) * 1e5 + x;
+  y = (rowind + 13) * 1e5 + y;
+  x(prec == -1) = ((2*eastp(prec == -1) - 1) * ...
+                   floor(4 * 100/90 + 0.5) + 20) * 1e5;
+  y(prec == -1) = 20e5;
+  x(~ok) = nan;
+  y(~ok) = nan;
+  northp(~ok) = false;
+  zone(~ok) = -4;
+  prec(~ok) = -2;
+end
+
+function [x, y, zone, northp, prec] = mgrs_inv_upss(mgrs)
+  zone = zeros(size(mgrs,1),1);
+  ok = zone == 0;
+  northp = ~ok;
+  eastp = lookup('AB', mgrs(:,1));
+  ok = ok & eastp >= 0;
+  eastp = eastp > 0;
+  colind = lookup('JKLPQRSTUXYZ', mgrs(:, 2));
+  colind(eastp) = lookup('ABCFGHJKLPQR', mgrs(eastp, 2)) + 12;
+  colind(eastp & colind < 12) = -1;
+  ok = ok & (colind < 0 | mod(floor(colind / 12) + eastp, 2) == 0);
+  rowind = lookup('ABCDEFGHJKLMNPQRSTUVWXYZ', mgrs(:, 3));
+  [x, y, prec] = decodexy(mgrs(:, 4:end));
+  prec(mgrs(:,2) == ' ') = -1;
+  ok = ok & (prec == -1 | (colind >= 0 & rowind >= 0));
+  x = (colind + 8) * 1e5 + x;
+  y = (rowind + 8) * 1e5 + y;
+  x(prec == -1) = ((2*eastp(prec == -1) - 1) * ...
+                   floor(4 * 100/90 + 0.5) + 20) * 1e5;
+  y(prec == -1) = 20e5;
+  x(~ok) = nan;
+  y(~ok) = nan;
+  zone(~ok) = -4;
+  prec(~ok) = -2;
+end
+
+function [x, y, prec] = decodexy(xy)
+  num = size(xy, 1);
+  x = nan(num, 1); y = x;
+  len = strlen(xy);
+  prec = len / 2;
+  digits = sum(isspace(xy) | isstrprop(xy, 'digit'), 2) == size(xy, 2);
+  ok = len < 22 & mod(len, 2) == 0 & digits;
+  prec(~ok) = -2;
+  if ~any(ok), return, end
+  x(prec == 0) = 0.5e5; y(prec == 0) = 0.5e5;
+  minprec = max(1,min(prec(ok))); maxprec = max(prec(ok));
+  for p = minprec:maxprec
+    m = 1e5 / 10^p;
+    x(prec == p) = str2double(cellstr(xy(prec == p, 0+(1:p)))) * m + m/2;
+    y(prec == p) = str2double(cellstr(xy(prec == p, p+(1:p)))) * m + m/2;
+  end
+end
+
+function irow = utmrow(iband, icol, irow)
+% Input is MGRS (periodic) row index and output is true row index.  Band
+% index is in [-10, 10) (as returned by LatitudeBand).  Column index
+% origin is easting = 100km.  Returns 100  if irow and iband are
+% incompatible.  Row index origin is equator.
+
+% Estimate center row number for latitude band
+% 90 deg = 100 tiles; 1 band = 8 deg = 100*8/90 tiles
+  c = 100 * (8 * iband + 4)/90;
+  northp = iband >= 0;
+  minrow = cvmgt(floor(c - 4.3 - 0.1 * northp), -90, iband > -10);
+  maxrow = cvmgt(floor(c + 4.4 - 0.1 * northp),  94, iband <   9);
+  baserow = floor((minrow + maxrow) / 2) - 10;
+  irow = mod(irow - baserow, 20) + baserow;
+  fix = irow < minrow | irow > maxrow;
+  if ~any(fix), return, end
+  % Northing = 71*100km and 80*100km intersect band boundaries
+  % The following deals with these special cases.
+  % Fold [-10,-1] -> [9,0]
+  sband = cvmgt(iband, -iband - 1, iband >= 0);
+  % Fold [-90,-1] -> [89,0]
+  srow = cvmgt(irow, -irow - 1, irow >= 0);
+  % Fold [4,7] -> [3,0]
+  scol = cvmgt(icol, -icol + 7, icol < 4);
+  irow(fix & ~( (srow == 70 & sband == 8 & scol >= 2) | ...
+                (srow == 71 & sband == 7 & scol <= 2) | ...
+                (srow == 79 & sband == 9 & scol >= 1) | ...
+                (srow == 80 & sband == 8 & scol <= 1) ) ) = 100;
+end
+
+function len = strlen(strings)
+  num = size(strings, 1);
+  len = repmat(size(strings, 2), num, 1);
+  strings = strings(:);
+  r = cumsum(ones(num,1));
+  d = 1;
+  while any(d)
+    d = len > 0 & strings(num * (max(len, 1) - 1) + r) == ' ';
+    len(d) = len(d) - 1;
+  end
+end
+
+function ind = lookup(str, test)
+% str is uppercase row string to look up in. test is col array to lookup
+  q = str - 'A' + 1;
+  t = zeros(27,1);
+  t(q) = cumsum(ones(length(q),1));
+  test = test - 'A' + 1;
+  test(~(test >= 1 & test <= 26)) = 27;
+  ind = t(test) - 1;
+end
diff --git a/matlab/geographiclib/polarst_fwd.m b/matlab/geographiclib/polarst_fwd.m
new file mode 100644
index 0000000..49ccc1a
--- /dev/null
+++ b/matlab/geographiclib/polarst_fwd.m
@@ -0,0 +1,67 @@
+function [x, y, gam, k] = polarst_fwd(isnorth, lat, lon, ellipsoid)
+%POLARST_FWD  Forward polar stereographic projection
+%
+%   [x, y] = POLARST_FWD(isnorth, lat, lon)
+%   [x, y, gam, k] = POLARST_FWD(isnorth, lat, lon, ellipsoid)
+%
+%   performs the forward polar stereographic projection of points (lat,lon)
+%   to (x,y) using the north (south) as the center of projection depending
+%   on whether isnortp is 1 (0).  These input arguments can be scalars or
+%   arrays of equal size.  The ellipsoid vector is of the form [a, e],
+%   where a is the equatorial radius in meters, e is the eccentricity.  If
+%   ellipsoid is omitted, the WGS84 ellipsoid (more precisely, the value
+%   returned by defaultellipsoid) is used.  The inverse projection is given
+%   by polarst_inv.
+%
+%   gam and k give metric properties of the projection at (lat,lon); gam is
+%   the meridian convergence at the point and k is the scale.
+%
+%   lat, lon, gam are in degrees.  The projected coordinates x, y are in
+%   meters (more precisely the units used for the equatorial radius).  k is
+%   dimensionless.
+%
+%   See also POLARST_INV, UTMUPS_FWD, UTMUPS_INV, DEFAULTELLIPSOID.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  narginchk(3, 4)
+  if nargin < 4, ellipsoid = defaultellipsoid; end
+  try
+    [~] = isnorth + lat + lon;
+  catch
+    error('isnorth, lat, lon have incompatible sizes')
+  end
+  if length(ellipsoid(:)) ~= 2
+    error('ellipsoid must be a vector of size 2')
+  end
+
+  degree = pi/180;
+  overflow = 1/eps^2;
+  a = ellipsoid(1);
+  e2 = ellipsoid(2)^2;
+  e2m = 1 - e2;
+  c = sqrt(e2m) * exp(eatanhe(1, e2));
+
+  isnorth = 2 * logical(isnorth) - 1;
+  lat = lat .* isnorth;
+  phi = lat * degree;
+  lam = AngNormalize(lon) .* degree;
+  tau = tan(phi); tau(abs(lat) == 90) = sign(lat(abs(lat) == 90)) * overflow;
+  taup = taupf(tau, e2);
+  rho = hypot(1, taup) + abs(taup);
+  rho(taup >= 0) = cvmgt(1./rho(taup >= 0), 0, lat(taup >= 0) ~= 90);
+  rho = rho * (2 * a / c);
+  lon = AngNormalize(lon);
+  x = rho .* sin(lam); x(lon == -180) = 0;
+  y = -isnorth .* rho .* cos(lam); x(abs(lon) == 90) = 0;
+  if nargout > 2
+    gam = isnorth .* lon;
+    if nargout > 3
+      secphi = hypot(1, tau);
+      k = (rho / a) .* secphi .* sqrt(e2m + e2 .* secphi.^-2);
+      k(lat == 90) = 1;
+    end
+  end
+end
diff --git a/matlab/geographiclib/polarst_inv.m b/matlab/geographiclib/polarst_inv.m
new file mode 100644
index 0000000..f8f1263
--- /dev/null
+++ b/matlab/geographiclib/polarst_inv.m
@@ -0,0 +1,64 @@
+function [lat, lon, gam, k] = polarst_inv(isnorth, x, y, ellipsoid)
+%POLARST_INV  Inverse polar stereographic projection
+%
+%   [lat, lon] = POLARST_INV(isnorth, x, y)
+%   [lat, lon, gam, k] = POLARST_INV(isnorth, x, y, ellipsoid)
+%
+%   performs the inverse polar stereographic projection of points (x,y) to
+%   (lat,lon) using the north (south) as the center of projection depending
+%   on whether isnortp is 1 (0).  These input arguments can be scalars or
+%   arrays of equal size.  The ellipsoid vector is of the form [a, e],
+%   where a is the equatorial radius in meters, e is the eccentricity.  If
+%   ellipsoid is omitted, the WGS84 ellipsoid (more precisely, the value
+%   returned by defaultellipsoid) is used.  The forward projection is given
+%   by polarst_fwd.
+%
+%   gam and k give metric properties of the projection at (lat,lon); gam is
+%   the meridian convergence at the point and k is the scale.
+%
+%   lat, lon, gam are in degrees.  The projected coordinates x, y are in
+%   meters (more precisely the units used for the equatorial radius).  k is
+%   dimensionless.
+%
+%   See also POLARST_FWD, UTMUPS_FWD, UTMUPS_INV, DEFAULTELLIPSOID.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  narginchk(3, 4)
+  if nargin < 4, ellipsoid = defaultellipsoid; end
+  try
+    [~] = isnorth + x + y;
+  catch
+    error('isnorth, x, y have incompatible sizes')
+  end
+  if length(ellipsoid(:)) ~= 2
+    error('ellipsoid must be a vector of size 2')
+  end
+
+  degree = pi/180;
+  a = ellipsoid(1);
+  e2 = ellipsoid(2)^2;
+  e2m = 1 - e2;
+  c = sqrt(e2m) * exp(eatanhe(1, e2));
+
+  isnorth = 2 * logical(isnorth) - 1;
+  rho = hypot(x, y);
+  t = rho / (2 * a / c);
+  taup = (1 ./ t - t) / 2;
+  tau = tauf(taup, e2);
+  phi = atan(tau);
+  lat =  phi / degree;
+  lat(rho == 0) = 90;
+  lat = isnorth .* lat;
+  lon = 0 - atan2( -x, -isnorth .* y) / degree;
+  if nargout > 2
+    gam = isnorth .* lon;
+    if nargout > 3
+      secphi = hypot(1, tau);
+      k = (rho / a) .* secphi .* sqrt(e2m + e2 .* secphi.^-2);
+      k(rho == 0) = 1;
+    end
+  end
+end
diff --git a/matlab/private/A1m1f.m b/matlab/geographiclib/private/A1m1f.m
similarity index 68%
rename from matlab/private/A1m1f.m
rename to matlab/geographiclib/private/A1m1f.m
index f83c615..4522820 100644
--- a/matlab/private/A1m1f.m
+++ b/matlab/geographiclib/private/A1m1f.m
@@ -1,7 +1,7 @@
 function A1m1 = A1m1f(epsi)
 %A1M1F  Evaluate A_1 - 1
 %
-%   A1M1 = A1M1F(EPSI) evaluates A_1 - 1 using Eq. (17).  EPSI and A1M1 are
+%   A1m1 = A1M1F(epsi) evaluates A_1 - 1 using Eq. (17).  epsi and A1m1 are
 %   K x 1 arrays.
 
   eps2 = epsi.^2;
diff --git a/matlab/private/A2m1f.m b/matlab/geographiclib/private/A2m1f.m
similarity index 69%
rename from matlab/private/A2m1f.m
rename to matlab/geographiclib/private/A2m1f.m
index 3de421e..3d6179e 100644
--- a/matlab/private/A2m1f.m
+++ b/matlab/geographiclib/private/A2m1f.m
@@ -1,7 +1,7 @@
 function A2m1 = A2m1f(epsi)
 %A2M1F  Evaluate A_2 - 1
 %
-%   A2M1 = A2M1F(EPSI) evaluates A_2 - 1 using Eq. (42).  EPSI and A2M1 are
+%   A2m1 = A2M1F(epsi) evaluates A_2 - 1 using Eq. (42).  epsi and A2m1 are
 %   K x 1 arrays.
 
   eps2 = epsi.^2;
diff --git a/matlab/private/A3coeff.m b/matlab/geographiclib/private/A3coeff.m
similarity index 68%
rename from matlab/private/A3coeff.m
rename to matlab/geographiclib/private/A3coeff.m
index 6ded9c2..99f66b5 100644
--- a/matlab/private/A3coeff.m
+++ b/matlab/geographiclib/private/A3coeff.m
@@ -1,8 +1,8 @@
 function A3x = A3coeff(n)
 %A3COEFF  Evaluate coefficients for A_3
 %
-%   A3x = A3COEFF(N) evaluates the coefficients of epsilon^l in Eq. (24).  N
-%   is a scalar.  A3x is a 1 x 6 array.
+%   A3x = A3COEFF(n) evaluates the coefficients of epsilon^l in Eq. (24).
+%   n is a scalar.  A3x is a 1 x 6 array.
 
   nA3 = 6;
   A3x = zeros(1, nA3);
diff --git a/matlab/private/A3f.m b/matlab/geographiclib/private/A3f.m
similarity index 57%
rename from matlab/private/A3f.m
rename to matlab/geographiclib/private/A3f.m
index a747d75..be9fed9 100644
--- a/matlab/private/A3f.m
+++ b/matlab/geographiclib/private/A3f.m
@@ -1,8 +1,8 @@
 function A3 = A3f(epsi, A3x)
 %A3F  Evaluate A_3
 %
-%   A3 = A3F(EPSI, A3X) evaluates A_3 using Eq. (24) and the coefficient
-%   vector A3X.  EPSI and A3 are K x 1 arrays.  A3X is a 1 x 6 array.
+%   A3 = A3F(epsi, A3x) evaluates A_3 using Eq. (24) and the coefficient
+%   vector A3x.  epsi and A3 are K x 1 arrays.  A3x is a 1 x 6 array.
 
   nA3 = 6;
   A3 = zeros(length(epsi), 1);
diff --git a/matlab/private/AngDiff.m b/matlab/geographiclib/private/AngDiff.m
similarity index 67%
rename from matlab/private/AngDiff.m
rename to matlab/geographiclib/private/AngDiff.m
index d09faa4..60d1bbf 100644
--- a/matlab/private/AngDiff.m
+++ b/matlab/geographiclib/private/AngDiff.m
@@ -1,8 +1,8 @@
 function d = AngDiff(x, y)
 %ANGDIFF  Compute angle difference accurately
 %
-%   D = ANGDIFF(X, Y) computes Y - X, reduces the result to (-180,180] and
-%   rounds the result.  X and Y must be in [-180,180].  X and Y can be any
+%   d = ANGDIFF(x, y) computes y - x, reduces the result to (-180,180] and
+%   rounds the result.  x and y must be in [-180,180].  x and y can be any
 %   compatible shapes.
 
   [d, t] = sumx(-x, y);
diff --git a/matlab/private/AngNormalize.m b/matlab/geographiclib/private/AngNormalize.m
similarity index 60%
rename from matlab/private/AngNormalize.m
rename to matlab/geographiclib/private/AngNormalize.m
index e340544..28f42bb 100644
--- a/matlab/private/AngNormalize.m
+++ b/matlab/geographiclib/private/AngNormalize.m
@@ -1,8 +1,8 @@
 function x = AngNormalize(x)
 %ANGNORMALIZE  Reduce angle to range [-180, 180)
 %
-%   X = ANGNORMALIZE(X) reduces angles in [-540, 540) to the range
-%   [-180, 180).  X can be any shape.
+%   x = ANGNORMALIZE(x) reduces angles in [-540, 540) to the range
+%   [-180, 180).  x can be any shape.
 
   x(x >= 180) = x(x >= 180) - 360;
   x(x < -180) = x(x < -180) + 360;
diff --git a/matlab/private/AngNormalize2.m b/matlab/geographiclib/private/AngNormalize2.m
similarity index 60%
rename from matlab/private/AngNormalize2.m
rename to matlab/geographiclib/private/AngNormalize2.m
index 6cc5a99..6c89f98 100644
--- a/matlab/private/AngNormalize2.m
+++ b/matlab/geographiclib/private/AngNormalize2.m
@@ -1,8 +1,8 @@
 function x = AngNormalize2(x)
 %ANGNORMALIZE2  Reduce any angle to range [-180, 180)
 %
-%   X = ANGNORMALIZE(X) reduces arbitrary angles to the range [-180, 180).
-%   X can be any shape.
+%   x = ANGNORMALIZE(x) reduces arbitrary angles to the range [-180, 180).
+%   x can be any shape.
 
   x = AngNormalize(rem(x, 360));
 end
diff --git a/matlab/private/AngRound.m b/matlab/geographiclib/private/AngRound.m
similarity index 64%
rename from matlab/private/AngRound.m
rename to matlab/geographiclib/private/AngRound.m
index e468b09..7e5623c 100644
--- a/matlab/private/AngRound.m
+++ b/matlab/geographiclib/private/AngRound.m
@@ -1,8 +1,8 @@
 function y = AngRound(x)
 %ANGROUND  Round tiny values so that tiny values become zero.
 %
-%   Y = ANGROUND(X) rounds X by adding and subtracting 1/16 to it if it is
-%   small.  X and Y can be any shape.
+%   y = ANGROUND(x) rounds x by adding and subtracting 1/16 to it if it is
+%   small.  x can be any shape.
 
   z = 1/16;
   y = abs(x);
diff --git a/matlab/private/C1f.m b/matlab/geographiclib/private/C1f.m
similarity index 87%
rename from matlab/private/C1f.m
rename to matlab/geographiclib/private/C1f.m
index 6d022b0..d0e5cb1 100644
--- a/matlab/private/C1f.m
+++ b/matlab/geographiclib/private/C1f.m
@@ -1,7 +1,7 @@
 function C1 = C1f(epsi)
 %C1F  Evaluate C_{1,k}
 %
-%   C1 = C1F(EPSI) evaluates C_{1,l} using Eq. (18).  EPSI is a K x 1
+%   C1 = C1F(epsi) evaluates C_{1,l} using Eq. (18).  epsi is a K x 1
 %   array and C1 is a K x 6 array.
 
   nC1 = 6;
diff --git a/matlab/geographiclib/private/C1pf.m b/matlab/geographiclib/private/C1pf.m
new file mode 100644
index 0000000..221e9bf
--- /dev/null
+++ b/matlab/geographiclib/private/C1pf.m
@@ -0,0 +1,22 @@
+function C1p = C1pf(epsi)
+%C1PF  Evaluate C'_{1,k}
+%
+%   C1p = C1PF(epsi) evaluates C'_{1,l} using Eq. (21).  epsi is an
+%   K x 1 array and C1 is a K x 6 array.
+
+  nC1p = 6;
+  C1p = zeros(length(epsi), nC1p);
+  eps2 = epsi.^2;
+  d = epsi;
+  C1p(:,1) = d.*(eps2.*(205*eps2-432)+768)/1536;
+  d = d.*epsi;
+  C1p(:,2) = d.*(eps2.*(4005*eps2-4736)+3840)/12288;
+  d = d.*epsi;
+  C1p(:,3) = d.*(116-225*eps2)/384;
+  d = d.*epsi;
+  C1p(:,4) = d.*(2695-7173*eps2)/7680;
+  d = d.*epsi;
+  C1p(:,5) = 3467*d/7680;
+  d = d.*epsi;
+  C1p(:,6) = 38081*d/61440;
+end
diff --git a/matlab/private/C2f.m b/matlab/geographiclib/private/C2f.m
similarity index 87%
rename from matlab/private/C2f.m
rename to matlab/geographiclib/private/C2f.m
index 09be4b4..9678e60 100644
--- a/matlab/private/C2f.m
+++ b/matlab/geographiclib/private/C2f.m
@@ -1,7 +1,7 @@
 function C2 = C2f(epsi)
 %C2F  Evaluate C_{2,k}
 %
-%   C2 = C2F(EPSI) evaluates C_{2,l} using Eq. (43).  EPSI is an
+%   C2 = C2F(epsi) evaluates C_{2,l} using Eq. (43).  epsi is an
 %   K x 1 array and C2 is a K x 6 array.
 
   nC2 = 6;
diff --git a/matlab/private/C3coeff.m b/matlab/geographiclib/private/C3coeff.m
similarity index 83%
rename from matlab/private/C3coeff.m
rename to matlab/geographiclib/private/C3coeff.m
index 12c4199..6361e70 100644
--- a/matlab/private/C3coeff.m
+++ b/matlab/geographiclib/private/C3coeff.m
@@ -1,8 +1,8 @@
 function C3x = C3coeff(n)
 %C3COEFF  Evaluate coefficients for C_3
 %
-%   C3x = C3COEFF(N) evaluates the coefficients of epsilon^l in Eq. (25).
-%   N is a scalar.  C3x is a 1 x 15 array.
+%   C3x = C3COEFF(n) evaluates the coefficients of epsilon^l in Eq. (25).
+%   n is a scalar.  C3x is a 1 x 15 array.
 
   nC3 = 6;
   nC3x = (nC3 * (nC3 - 1)) / 2;
diff --git a/matlab/private/C3f.m b/matlab/geographiclib/private/C3f.m
similarity index 77%
rename from matlab/private/C3f.m
rename to matlab/geographiclib/private/C3f.m
index 1fae41b..11bf1b2 100644
--- a/matlab/private/C3f.m
+++ b/matlab/geographiclib/private/C3f.m
@@ -1,8 +1,8 @@
 function C3 = C3f(epsi, C3x)
 %C3F  Evaluate C_3
 %
-%   C3 = C3F(EPSI, C3X) evaluates C_{3,l} using Eq. (25) and the
-%   coefficient vector C3X.  EPSI is a K x 1 array.  C3X is a 1 x 15 array.
+%   C3 = C3F(epsi, C3x) evaluates C_{3,l} using Eq. (25) and the
+%   coefficient vector C3x.  epsi is a K x 1 array.  C3x is a 1 x 15 array.
 %   C3 is a K x 5 array.
 
   nC3 = 6;
diff --git a/matlab/private/C4coeff.m b/matlab/geographiclib/private/C4coeff.m
similarity index 88%
rename from matlab/private/C4coeff.m
rename to matlab/geographiclib/private/C4coeff.m
index 2339118..812618e 100644
--- a/matlab/private/C4coeff.m
+++ b/matlab/geographiclib/private/C4coeff.m
@@ -1,8 +1,8 @@
 function C4x = C4coeff(n)
 %C4COEFF  Evaluate coefficients for C_4
 %
-%   C4x = C4COEFF(N) evaluates the coefficients of epsilon^l in expansion
-%   of the area (Eq. (65) expressed in terms of n and epsi).  N is a
+%   C4x = C4COEFF(n) evaluates the coefficients of epsilon^l in expansion
+%   of the area (Eq. (65) expressed in terms of n and epsi).  n is a
 %   scalar.  C4x is a 1 x 21 array.
 
   nC4 = 6;
diff --git a/matlab/private/C4f.m b/matlab/geographiclib/private/C4f.m
similarity index 79%
rename from matlab/private/C4f.m
rename to matlab/geographiclib/private/C4f.m
index c481b7f..dde7a8e 100644
--- a/matlab/private/C4f.m
+++ b/matlab/geographiclib/private/C4f.m
@@ -1,9 +1,9 @@
 function C4 = C4f(epsi, C4x)
 %C4F  Evaluate C_4
 %
-%   C4 = C4F(EPSI, C4X) evaluates C_{4,l} in the expansion for the area
+%   C4 = C4F(epsi, C4x) evaluates C_{4,l} in the expansion for the area
 %   (Eq. (65) expressed in terms of n and epsi) using the coefficient
-%   vector C4X.  EPSI is a K x 1 array.  C4X is a 1 x 21 array.  C4 is a
+%   vector C4x.  epsi is a K x 1 array.  C4x is a 1 x 21 array.  C4 is a
 %   K x 6 array.
 
   nC4 = 6;
diff --git a/matlab/private/G4coeff.m b/matlab/geographiclib/private/G4coeff.m
similarity index 94%
rename from matlab/private/G4coeff.m
rename to matlab/geographiclib/private/G4coeff.m
index d0ca864..970c900 100644
--- a/matlab/private/G4coeff.m
+++ b/matlab/geographiclib/private/G4coeff.m
@@ -1,8 +1,8 @@
 function G4x = G4coeff(n)
 %G4COEFF  Evaluate coefficients for C_4 for great ellipse
 %
-%   G4x = G4COEFF(N) evaluates the coefficients of epsilon^l in expansion
-%   of the greate ellipse area (expressed in terms of n and epsi).  N is a
+%   G4x = G4COEFF(n) evaluates the coefficients of epsilon^l in expansion
+%   of the greate ellipse area (expressed in terms of n and epsi).  n is a
 %   scalar.  G4x is a 1 x 21 array.
 
   nG4 = 6;
@@ -30,4 +30,3 @@ function G4x = G4coeff(n)
   G4x(19+1) = -5453/1317888;
   G4x(20+1) = 21/146432;
 end
-
diff --git a/matlab/geographiclib/private/GeoRotation.m b/matlab/geographiclib/private/GeoRotation.m
new file mode 100644
index 0000000..056192e
--- /dev/null
+++ b/matlab/geographiclib/private/GeoRotation.m
@@ -0,0 +1,26 @@
+function M = GeoRotation(sphi, cphi, slam, clam)
+%GEOROTATION The rotation from geodetic to geocentric
+%
+%   M = GeoRotation(sphi, cphi, slam, clam)
+%
+%   sphi, cphi, slam, clam must all have the same shape, S.  M has the shape
+%   [3, 3, S].
+
+% This rotation matrix is given by the following quaternion operations
+% qrot(lam, [0,0,1]) * qrot(phi, [0,-1,0]) * [1,1,1,1]/2
+% or
+% qrot(pi/2 + lam, [0,0,1]) * qrot(-pi/2 + phi , [-1,0,0])
+% where
+% qrot(t,v) = [cos(t/2), sin(t/2)*v[1], sin(t/2)*v[2], sin(t/2)*v[3]]
+  S = size(sphi);
+  M = zeros(9, prod(S));
+  sphi = sphi(:); cphi = cphi(:);
+  slam = slam(:); clam = clam(:);
+  % Local X axis (east) in geocentric coords
+  M(1,:) = -slam;         M(2,:) =  clam;         M(3,:) = 0;
+  % Local Y axis (north) in geocentric coords
+  M(4,:) = -clam .* sphi; M(5,:) = -slam .* sphi; M(6,:) = cphi;
+  % Local Z axis (up) in geocentric coords
+  M(7,:) =  clam .* cphi; M(8,:) =  slam .* cphi; M(9,:) = sphi;
+  M = reshape(M, [3, 3, S]);
+end
diff --git a/matlab/private/SinCosSeries.m b/matlab/geographiclib/private/SinCosSeries.m
similarity index 71%
rename from matlab/private/SinCosSeries.m
rename to matlab/geographiclib/private/SinCosSeries.m
index e5531fc..fa36d43 100644
--- a/matlab/private/SinCosSeries.m
+++ b/matlab/geographiclib/private/SinCosSeries.m
@@ -1,18 +1,15 @@
 function y = SinCosSeries(sinp, sinx, cosx, c)
 %SINSCOSERIES  Evaluate a sine or cosine series using Clenshaw summation
 %
-%   Y = SINCOSSERIES(SINP, SINX, COSX, C) evaluate
+%   y = SINCOSSERIES(sinp, sinx, cosx, c) evaluate
 %     y = sum(c[i] * sin( 2*i    * x), i, 1, n), if  sinp
 %     y = sum(c[i] * cos((2*i-1) * x), i, 1, n), if ~sinp
 %
-%   where n is the size of C.  x is given via its sine and cosine in SINX
-%   and COSX.  SINP is a scalar.  SINX, COSX, and Y are K x 1 arrays.  C is
+%   where n is the size of c.  x is given via its sine and cosine in sinx
+%   and cosx.  sinp is a scalar.  sinx, cosx, and y are K x 1 arrays.  c is
 %   a K x N array.
 
-  if isempty(sinx)
-    y = [];
-    return
-  end
+  if isempty(sinx), y = []; return, end
   n = size(c, 2);
   ar = 2 * (cosx - sinx) .* (cosx + sinx);
   y1 = zeros(length(sinx), 1);
diff --git a/matlab/geographiclib/private/cbrtx.m b/matlab/geographiclib/private/cbrtx.m
new file mode 100644
index 0000000..e15c0ed
--- /dev/null
+++ b/matlab/geographiclib/private/cbrtx.m
@@ -0,0 +1,9 @@
+function y = cbrtx(x)
+%CBRTX   The real cube root
+%
+%   CBRTX(x) is the real cube root of x (assuming x is real).  x
+%   can be any shape.
+
+  y = abs(x).^(1/3);
+  y(x < 0) = -y(x < 0);
+end
diff --git a/matlab/private/cvmgt.m b/matlab/geographiclib/private/cvmgt.m
similarity index 58%
rename from matlab/private/cvmgt.m
rename to matlab/geographiclib/private/cvmgt.m
index 2eb12e5..af3982c 100644
--- a/matlab/private/cvmgt.m
+++ b/matlab/geographiclib/private/cvmgt.m
@@ -1,13 +1,13 @@
 function z = cvmgt(x, y, p)
 %CVMGT  Conditional merge of two vectors
 %
-%   Z = CVMGT(X, Y, P) return a vector Z whose elements are X if P is true
-%   and Y otherwise.  P, X, and Y should be the same shape except that X
-%   and Y may be scalars.  CVMGT stands for conditional vector merge true
+%   z = CVMGT(x, y, p) return a vector z whose elements are x if p is true
+%   and y otherwise.  p, x, and y should be the same shape except that x
+%   and y may be scalars.  CVMGT stands for conditional vector merge true
 %   (an intrinsic function for the Cray fortran compiler).  It implements
 %   the C++ statement
 %
-%     Z = P ? X : Y;
+%     z = p ? x : y;
 
   z = zeros(size(p));
   if isscalar(x)
diff --git a/matlab/geographiclib/private/eatanhe.m b/matlab/geographiclib/private/eatanhe.m
new file mode 100644
index 0000000..5e8297a
--- /dev/null
+++ b/matlab/geographiclib/private/eatanhe.m
@@ -0,0 +1,13 @@
+function y = eatanhe(x, e2)
+%EATANHE   e*atanh(e*x)
+%
+%   EATANHE(x, e2) returns e*atanh(e*x) where e = sqrt(e2)
+%   e2 is a scalar; x can be any shape.
+
+  e = sqrt(abs(e2));
+  if (e2 >= 0)
+    y = e * atanh(e * x);
+  else
+    y = -e * atan(e * x);
+  end
+end
diff --git a/matlab/geographiclib/private/geoid_file.m b/matlab/geographiclib/private/geoid_file.m
new file mode 100644
index 0000000..594495f
--- /dev/null
+++ b/matlab/geographiclib/private/geoid_file.m
@@ -0,0 +1,27 @@
+function filename = geoid_file(name, dir)
+%GEOID_FILE  Return filename for geoid data
+%
+%   filename = geoid_file(name, dir).  See the documentation on geoid_load.
+
+  if nargin < 1 || isempty(name)
+    name = getenv('GEOGRAPHICLIB_GEOID_NAME');
+    if isempty(name)
+      name = 'egm96-5';
+    end
+  end
+  if nargin < 2 || isempty(dir)
+    dir = getenv('GEOGRAPHICLIB_GEOID_PATH');
+    if isempty(dir)
+      dir = getenv('GEOGRAPHICLIB_DATA');
+      if isempty(dir)
+        if ispc
+          dir = 'C:/ProgramData/GeographicLib';
+        else
+          dir = '/usr/local/share/GeographicLib';
+        end
+      end
+      dir = [dir, '/geoids'];
+    end
+  end
+  filename = [dir, '/', name, '.pgm'];
+end
diff --git a/matlab/geographiclib/private/geoid_load_file.m b/matlab/geographiclib/private/geoid_load_file.m
new file mode 100644
index 0000000..2778362
--- /dev/null
+++ b/matlab/geographiclib/private/geoid_load_file.m
@@ -0,0 +1,32 @@
+function geoid = geoid_load_file(filename)
+%GEOID_LOAD_FILE  Loads geoid data from filename
+
+  geoid.file = filename; geoid.offset = NaN; geoid.scale = NaN;
+  fid = fopen(geoid.file, 'r');
+  if fid == -1, error(['Cannot open ', geoid.file]), end
+  for i = 1:16
+    if isfinite(geoid.offset) && isfinite(geoid.scale), break, end
+    text = fgetl(fid);
+    if ~ischar(text), continue, end
+    text = strsplit(text, ' ');
+    if length(text) == 3
+      if strcmp(text{2}, 'Offset')
+        geoid.offset = str2double(text{3});
+      elseif strcmp(text{2}, 'Scale')
+        geoid.scale = str2double(text{3});
+      end
+    elseif length(text) == 2
+      break
+    end
+  end
+  fclose(fid);
+  if ~isfinite(geoid.offset), error('Cannot find offset'), end
+  if ~isfinite(geoid.scale), error('Cannot find scale'), end
+  geoid.im = imread(geoid.file);
+  if ~isa(geoid.im, 'uint16'), error('Wrong image type'), end
+  geoid.h = size(geoid.im, 1);
+  geoid.w = size(geoid.im, 2);
+  if ~(bitand(geoid.w, 1) == 0 && bitand(geoid.h, 1) == 1)
+    error('Image width/height not even/odd')
+  end
+end
diff --git a/matlab/geographiclib/private/norm2.m b/matlab/geographiclib/private/norm2.m
new file mode 100644
index 0000000..9bccb4b
--- /dev/null
+++ b/matlab/geographiclib/private/norm2.m
@@ -0,0 +1,10 @@
+function [x, y] = norm2(x, y)
+%NORM2  Normalize x and y
+%
+%   [x, y] = NORM2(x, y) normalize x and y so that x^2 + y^2 = 1.  x and y
+%   can be any shape.
+
+  r = hypot(x, y);
+  x = x ./ r;
+  y = y ./ r;
+end
diff --git a/matlab/private/sumx.m b/matlab/geographiclib/private/sumx.m
similarity index 59%
rename from matlab/private/sumx.m
rename to matlab/geographiclib/private/sumx.m
index d9b6118..0c9d268 100644
--- a/matlab/private/sumx.m
+++ b/matlab/geographiclib/private/sumx.m
@@ -1,8 +1,8 @@
 function [s, t] = sumx(u, v)
 %SUM   Error free sum
 %
-%   [S, T] = SUMX(U, V) returns the rounded sum U + V in S and the error in
-%   T, such that S + T = U + V, exactly.  U and V can be any compatible
+%   [s, t] = SUMX(u, v) returns the rounded sum u + v in s and the error in
+%   t, such that s + t = u + v, exactly.  u and v can be any compatible
 %   shapes.
 
   s = u + v;
diff --git a/matlab/geographiclib/private/swap.m b/matlab/geographiclib/private/swap.m
new file mode 100644
index 0000000..a70551a
--- /dev/null
+++ b/matlab/geographiclib/private/swap.m
@@ -0,0 +1,5 @@
+function [y, x] = swap(x, y)
+%SWAP  Swap two variables.
+%
+%   [a, b] = SWAP(x, y) sets A to Y and B to X.
+end
diff --git a/matlab/geographiclib/private/tauf.m b/matlab/geographiclib/private/tauf.m
new file mode 100644
index 0000000..b408047
--- /dev/null
+++ b/matlab/geographiclib/private/tauf.m
@@ -0,0 +1,22 @@
+function tau = tauf(taup, e2)
+%TAUF   tan(phi)
+%
+%   TAUF(taup, e2) returns tangent of phi in terms of taup the tangent of chi.
+%   e2, the square of the eccentricity, is a scalar; taup can be any shape.
+
+  numit = 5;
+  e2m = 1 - e2;
+  tau = taup / e2m;
+  stol = 0.1 * sqrt(eps) * max(1, abs(taup));
+  g = isfinite(tau);
+  for i = 1 : numit
+    if ~any(g), break, end
+    tau1 = hypot(1, tau);
+    sig = sinh( eatanhe( tau ./ tau1, e2 ) );
+    taupa = hypot(1, sig) .* tau - sig .* tau1;
+    dtau = (taup - taupa) .* (1 + e2m .* tau.^2) ./ ...
+           (e2m * tau1 .* hypot(1, taupa));
+    tau(g) = tau(g) + dtau(g);
+    g = g & abs(dtau) >= stol;
+  end
+end
diff --git a/matlab/geographiclib/private/taupf.m b/matlab/geographiclib/private/taupf.m
new file mode 100644
index 0000000..9d08571
--- /dev/null
+++ b/matlab/geographiclib/private/taupf.m
@@ -0,0 +1,10 @@
+function taup = taupf(tau, e2)
+%TAUPF   tan(chi)
+%
+%   TAUPF(tau, e2) returns tangent of chi in terms of tau the tangent of phi.
+%   e2, the square of the eccentricity, is a scalar; taup can be any shape.
+
+  tau1 = hypot(1, tau);
+  sig = sinh( eatanhe( tau ./ tau1, e2 ) );
+  taup = hypot(1, sig) .* tau - sig .* tau1;
+end
diff --git a/matlab/geographiclib/projdoc.m b/matlab/geographiclib/projdoc.m
new file mode 100644
index 0000000..bc0c0e5
--- /dev/null
+++ b/matlab/geographiclib/projdoc.m
@@ -0,0 +1,76 @@
+function projdoc
+%PROJDOC  Projections for an ellipsoid
+%
+%   This package implements five projections:
+%     * the transverse Mercator projection (tranmerc)
+%     * the polar stereographic projection (polarst)
+%     * the azimuthal equidistant projection (eqdazim)
+%     * the Cassini-Soldner projection (cassini)
+%     * the ellipsoidal gnomonic projection (gnomonic)
+%
+%   The package implements the forward projection (from geographic to
+%   projected coordinates) and inverse projection (from projected to
+%   geographic coordinates) with abbreviated function names (listed in
+%   parentheses in the list above) suffixed by _fwd and _inv.  For each
+%   function, metric properties of the projection are also returned.
+%
+%   The ellipsoidal gnomonic projection is defined by
+%
+%     [~,azi0,~,~,m,M] = geoddistance(lat0,lon0,lat,lon)
+%     rho = m./M, x = rho.*sind(azi0), y = rho.*cosd(azi0)
+%
+%   Obviously this is an azimuthal projection.  It also enjoys
+%   approximately the property of the spherical gnomonic projection, that
+%   geodesics map to straight lines.  The projection is derived in Section
+%   8 of
+%
+%     C. F. F. Karney, Algorithms for geodesics,
+%     J. Geodesy 87, 43-55 (2013);
+%     https://dx.doi.org/10.1007/s00190-012-0578-z
+%     Addenda: http://geographiclib.sf.net/geod-addenda.html
+%
+%   The parameters of the ellipsoid are specified by the optional ellipsoid
+%   argument to the routines.  This is a two-element vector of the form
+%   [a,e], where a is the equatorial radius, e is the eccentricity e =
+%   sqrt(a^2-b^2)/a, and b is the polar semi-axis.  Typically, a and b are
+%   measured in meters and the linear and area quantities returned by the
+%   routines are then in meters and meters^2.  However, other units can be
+%   employed.  If ellipsoid is omitted, then the WGS84 ellipsoid (more
+%   precisely, the value returned by defaultellipsoid) is assumed [6378137,
+%   0.0818191908426215] corresponding to a = 6378137 meters and a
+%   flattening f = (a-b)/a = 1/298.257223563.  The flattening and
+%   eccentricity are related by
+%
+%       e = sqrt(f * (2 - f))
+%       f = e^2 / (1 + sqrt(1 - e^2))
+%
+%   (The functions ecc2flat and flat2ecc implement these conversions.)  For
+%   a sphere, set e = 0; for a prolate ellipsoid (b > a), specify e as a
+%   pure imaginary number.
+%
+%   All angles (latitude, longitude, azimuth) are measured in degrees with
+%   latitudes increasing northwards, longitudes increasing eastwards, and
+%   azimuths measured clockwise from north.  For a point at a pole, the
+%   azimuth is defined by keeping the longitude fixed, writing lat =
+%   +/-(90-eps), and taking the limit eps -> 0+.
+%
+%   Restrictions on the inputs:
+%     * All latitudes must lie in [-90, 90].
+%     * All longitudes and azimuths must lie in [-540, 540).  On output,
+%       these quantities lie in [-180, 180).
+%     * The equatorial radius, a, must be positive.
+%     * The eccentricity, e, should be satisfy abs(e) < 0.2 in order to
+%       retain full accuracy (this corresponds to flattenings satisfying
+%       abs(f) <= 1/50, approximately).  This condition holds for most
+%       applications in geodesy.
+%
+%   See also TRANMERC_FWD, TRANMERC_INV, POLARST_FWD, POLARST_INV,
+%     EQDAZIM_FWD, EQDAZIM_INV, CASSINI_FWD, CASSINI_INV,
+%     GNOMONIC_FWD, GNOMONIC_INV, DEFAULTELLIPSOID, ECC2FLAT, FLAT2ECC.
+
+% Copyright (c) Charles Karney (2012-2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  help projdoc
+end
diff --git a/matlab/tranmerc_fwd.m b/matlab/geographiclib/tranmerc_fwd.m
similarity index 72%
rename from matlab/tranmerc_fwd.m
rename to matlab/geographiclib/tranmerc_fwd.m
index 6ba3e90..ac42614 100644
--- a/matlab/tranmerc_fwd.m
+++ b/matlab/geographiclib/tranmerc_fwd.m
@@ -1,24 +1,24 @@
 function [x, y, gam, k] = tranmerc_fwd(lat0, lon0, lat, lon, ellipsoid)
 %TRANMERC_FWD  Forward transverse Mercator projection
 %
-%   [X, Y] = TRANMERC_FWD(LAT0, LON0, LAT, LON)
-%   [X, Y, GAM, K] = TRANMERC_FWD(LAT0, LON0, LAT, LON, ELLIPSOID)
+%   [x, y] = TRANMERC_FWD(lat0, lon0, lat, lon)
+%   [x, y, gam, k] = TRANMERC_FWD(lat0, lon0, lat, lon, ellipsoid)
 %
-%   performs the forward transverse Mercator projection of points (LAT,LON)
-%   to (X,Y) using (LAT0,LON0) as the center of projection.  These input
-%   arguments can be scalars or arrays of equal size.  The ELLIPSOID vector
+%   performs the forward transverse Mercator projection of points (lat,lon)
+%   to (x,y) using (lat0,lon0) as the center of projection.  These input
+%   arguments can be scalars or arrays of equal size.  The ellipsoid vector
 %   is of the form [a, e], where a is the equatorial radius in meters, e is
 %   the eccentricity.  If ellipsoid is omitted, the WGS84 ellipsoid (more
-%   precisely, the value returned by DEFAULTELLIPSOID) is used.  GEODPROJ
+%   precisely, the value returned by defaultellipsoid) is used.  geodproj
 %   defines the projection and gives the restrictions on the allowed ranges
-%   of the arguments.  The inverse projection is given by TRANMERC_INV.
+%   of the arguments.  The inverse projection is given by tranmerc_inv.
 %
-%   GAM and K give metric properties of the projection at (LAT,LON); GAM is
-%   the meridian convergence at the point and K is the scale.
+%   gam and k give metric properties of the projection at (lat,lon); gam is
+%   the meridian convergence at the point and k is the scale.
 %
-%   LAT0, LON0, LAT, LON, GAM are in degrees.  The projected coordinates X,
-%   Y are in meters (more precisely the units used for the equatorial
-%   radius).  K is dimensionless.
+%   lat0, lon0, lat, lon, gam are in degrees.  The projected coordinates x,
+%   y are in meters (more precisely the units used for the equatorial
+%   radius).  k is dimensionless.
 %
 %   This implementation of the projection is based on the series method
 %   described in
@@ -34,23 +34,17 @@ function [x, y, gam, k] = tranmerc_fwd(lat0, lon0, lat, lon, ellipsoid)
 %   less than 1 mm within 7600 km of the central meridian).  The mapping
 %   can be continued accurately over the poles to the opposite meridian.
 %
-%   This routine depends on the MATLAB File Exchange package "Geodesics on
-%   an ellipsoid of revolution":
-%
-%     http://www.mathworks.com/matlabcentral/fileexchange/39108
-%
-%   See also GEODPROJ, TRANMERC_INV, GEODDISTANCE, DEFAULTELLIPSOID.
+%   See also TRANMERC_INV, UTMUPS_FWD, UTMUPS_INV, DEFAULTELLIPSOID.
 
-% Copyright (c) Charles Karney (2012) <charles at karney.com>.
+% Copyright (c) Charles Karney (2012-2015) <charles at karney.com>.
 %
-% This file was distributed with GeographicLib 1.29.
+% This file was distributed with GeographicLib 1.42.
 
-  if nargin < 4, error('Too few input arguments'), end
+  narginchk(4, 5)
   if nargin < 5, ellipsoid = defaultellipsoid; end
   try
-    Z = lat0 + lon0 + lat + lon;
-    Z = zeros(size(Z));
-  catch err
+    Z = zeros(size(lat0 + lon0 + lat + lon));
+  catch
     error('lat0, lon0, lat, lon have incompatible sizes')
   end
   if length(ellipsoid(:)) ~= 2
@@ -64,7 +58,7 @@ function [x, y, gam, k] = tranmerc_fwd(lat0, lon0, lat, lon, ellipsoid)
   f = ecc2flat(ellipsoid(2));
   e2 = f * (2 - f);
   e2m = 1 - e2;
-  cc = sqrt(e2m) * exp(e2 * atanhee(1, e2));
+  cc = sqrt(e2m) * exp(eatanhe(1, e2));
   n = f / (2 -f);
   alp = alpf(n);
   b1 = (1 - f) * (A1m1f(n) + 1);
@@ -135,7 +129,7 @@ function [x, y, gam, k] = tranmerc_fwd(lat0, lon0, lat, lon, ellipsoid)
   if isscalar(lat0) && lat0 == 0
     y0 = 0;
   else
-    [sbet0, cbet0] = SinCosNorm((1-f) * sind(lat0), cosd(lat0));
+    [sbet0, cbet0] = norm2((1-f) * sind(lat0), cosd(lat0));
     y0 = a1 * (atan2(sbet0, cbet0) + ...
                SinCosSeries(true, sbet0, cbet0, C1f(n)));
   end
@@ -159,12 +153,3 @@ function alp = alpf(n)
   nx = nx * n;
   alp(6) = 212378941*nx/319334400;
 end
-
-function taup = taupf(tau, e2)
-  tau1 = hypot(1, tau);
-  sig = sinh( e2 * atanhee(tau ./ tau1, e2) );
-  taup = hypot(1, sig) .* tau - sig .* tau1;
-  overflow = 1/eps^2;
-  c = ~(abs(tau) < overflow);
-  taup(c) = tau(c);
-end
diff --git a/matlab/tranmerc_inv.m b/matlab/geographiclib/tranmerc_inv.m
similarity index 68%
rename from matlab/tranmerc_inv.m
rename to matlab/geographiclib/tranmerc_inv.m
index b889d03..68b81e1 100644
--- a/matlab/tranmerc_inv.m
+++ b/matlab/geographiclib/tranmerc_inv.m
@@ -1,24 +1,24 @@
 function [lat, lon, gam, k] = tranmerc_inv(lat0, lon0, x, y, ellipsoid)
 %TRANMERC_INV  Inverse transverse Mercator projection
 %
-%   [LAT, LON] = TRANMERC_INV(LAT0, LON0, X, Y)
-%   [LAT, LON, GAM, K] = TRANMERC_INV(LAT0, LON0, X, Y, ELLIPSOID)
+%   [lat, lon] = TRANMERC_INV(lat0, lon0, x, y)
+%   [lat, lon, gam, k] = TRANMERC_INV(lat0, lon0, x, y, ellipsoid)
 %
-%   performs the inverse transverse Mercator projection of points (X,Y) to
-%   (LAT,LON) using (LAT0,LON0) as the center of projection.  These input
-%   arguments can be scalars or arrays of equal size.  The ELLIPSOID vector
+%   performs the inverse transverse Mercator projection of points (x,y) to
+%   (lat,lon) using (lat0,lon0) as the center of projection.  These input
+%   arguments can be scalars or arrays of equal size.  The ellipsoid vector
 %   is of the form [a, e], where a is the equatorial radius in meters, e is
 %   the eccentricity.  If ellipsoid is omitted, the WGS84 ellipsoid (more
-%   precisely, the value returned by DEFAULTELLIPSOID) is used.  GEODPROJ
+%   precisely, the value returned by defaultellipsoid) is used.  geodproj
 %   defines the projection and gives the restrictions on the allowed ranges
-%   of the arguments.  The forward projection is given by TRANMERC_FWD.
+%   of the arguments.  The forward projection is given by tranmerc_fwd.
 %
-%   GAM and K give metric properties of the projection at (LAT,LON); GAM is
-%   the meridian convergence at the point and K is the scale.
+%   gam and K give metric properties of the projection at (lat,lon); gam is
+%   the meridian convergence at the point and k is the scale.
 %
-%   LAT0, LON0, LAT, LON, GAM are in degrees.  The projected coordinates X,
-%   Y are in meters (more precisely the units used for the equatorial
-%   radius).  K is dimensionless.
+%   lat0, lon0, lat, lon, gam are in degrees.  The projected coordinates x,
+%   y are in meters (more precisely the units used for the equatorial
+%   radius).  k is dimensionless.
 %
 %   This implementation of the projection is based on the series method
 %   described in
@@ -34,23 +34,17 @@ function [lat, lon, gam, k] = tranmerc_inv(lat0, lon0, x, y, ellipsoid)
 %   less than 1 mm within 7600 km of the central meridian).  The mapping
 %   can be continued accurately over the poles to the opposite meridian.
 %
-%   This routine depends on the MATLAB File Exchange package "Geodesics on
-%   an ellipsoid of revolution":
-%
-%     http://www.mathworks.com/matlabcentral/fileexchange/39108
-%
-%   See also GEODPROJ, TRANMERC_FWD, GEODRECKON, DEFAULTELLIPSOID.
+%   See also, TRANMERC_FWD, UTMUPS_FWD, UTMUPS_INV, DEFAULTELLIPSOID.
 
-% Copyright (c) Charles Karney (2012) <charles at karney.com>.
+% Copyright (c) Charles Karney (2012-2015) <charles at karney.com>.
 %
-% This file was distributed with GeographicLib 1.29.
+% This file was distributed with GeographicLib 1.42.
 
-  if nargin < 4, error('Too few input arguments'), end
+  narginchk(4, 5)
   if nargin < 5, ellipsoid = defaultellipsoid; end
   try
-    Z = lat0 + lon0 + x + y;
-    Z = zeros(size(Z));
-  catch err
+    Z = zeros(size(lat0 + lon0 + x + y));
+  catch
     error('lat0, lon0, x, y have incompatible sizes')
   end
   if length(ellipsoid(:)) ~= 2
@@ -64,7 +58,7 @@ function [lat, lon, gam, k] = tranmerc_inv(lat0, lon0, x, y, ellipsoid)
   f = ecc2flat(ellipsoid(2));
   e2 = f * (2 - f);
   e2m = 1 - e2;
-  cc = sqrt(e2m) * exp(e2 * atanhee(1, e2));
+  cc = sqrt(e2m) * exp(eatanhe(1, e2));
   n = f / (2 -f);
   bet = betf(n);
   b1 = (1 - f) * (A1m1f(n) + 1);
@@ -73,7 +67,7 @@ function [lat, lon, gam, k] = tranmerc_inv(lat0, lon0, x, y, ellipsoid)
   if isscalar(lat0) && lat0 == 0
     y0 = 0;
   else
-    [sbet0, cbet0] = SinCosNorm((1-f) * sind(lat0), cosd(lat0));
+    [sbet0, cbet0] = norm2((1-f) * sind(lat0), cosd(lat0));
     y0 = a1 * (atan2(sbet0, cbet0) + ...
                SinCosSeries(true, sbet0, cbet0, C1f(n)));
   end
@@ -161,25 +155,3 @@ function bet = betf(n)
   nx = nx * n;
   bet(6) = 20648693*nx/638668800;
 end
-
-function tau = tauf(taup, e2)
-  overflow = 1/eps^2;
-  tol = 0.1 * sqrt(eps);
-  numit = 5;
-  e2m = 1 - e2;
-  tau = taup / e2m;
-  stol = tol * max(1, abs(taup));
-  g = ~(abs(taup) < overflow);
-  tau(g) = taup(g);
-  g = ~g;
-  for i = 1 : numit
-    if ~any(g), break, end
-    tau1 = hypot(1, tau);
-    sig = sinh(e2 * atanhee( tau ./ tau1, e2 ) );
-    taupa = hypot(1, sig) .* tau - sig .* tau1;
-    dtau = (taup - taupa) .* (1 + e2m .* tau.^2) ./ ...
-           (e2m * tau1 .* hypot(1, taupa));
-    tau(g) = tau(g) + dtau(g);
-    g = g & abs(dtau) >= stol;
-  end
-end
diff --git a/matlab/geographiclib/utmups_fwd.m b/matlab/geographiclib/utmups_fwd.m
new file mode 100644
index 0000000..ab90b14
--- /dev/null
+++ b/matlab/geographiclib/utmups_fwd.m
@@ -0,0 +1,120 @@
+function [x, y, zone, isnorth, gam, k] = utmups_fwd(lat, lon, setzone)
+%UTMUPS_FWD  Convert to UTM/UPS system
+%
+%   [x, y, zone, isnorth] = UTMUPS_FWD(lat, lon)
+%   [x, y, zone, isnorth, gam, k] = UTMUPS_FWD(lat, lon, setzone)
+%
+%   convert from geographical coordinates, (lat,lon), to the UTM/UPS
+%   system.  The output is (x,y) = (easting,northing), zone which is either
+%   the UTM zone or 0 for UPS, and a hemisphere selector, isnorth (0 for
+%   the southern hemisphere, 1 for the northern).  If setzone = -1 (the
+%   default), the standard choice is made between UTM and UPS and, if UTM,
+%   the standard zone is picked (the Norway and Svalbard exceptions are
+%   honored).  lat, lon, and setzone can be scalars or arrays of equal
+%   size.  The inverse operation is performed by utmups_inv.
+%
+%   gam and k give metric properties of the projection at (lat,lon); gam is
+%   the meridian convergence at the point and k is the scale.
+%
+%   lat, lon, gam are in degrees.  The projected coordinates x, y are in
+%   meters.  k is dimensionless.
+%
+%   The optional argument, setzone, allows the UTM/UPS and zone
+%   assignment to be overridden.  The choices are
+%        0, use UPS
+%        [1,60], use the corresponding UTM zone
+%       -1, use the standard assigment (the default)
+%       -2, use closest UTM zone
+%       -4, an undefined zone
+%
+%   The allowed values of (x,y) are
+%        UTM: x in [0 km, 1000 km]
+%             y in [0 km, 9600 km] for northern hemisphere
+%             y in [900 km, 10000 km] for southern hemisphere
+%        UPS: x and y in [1200 km, 2800 km] for northern hemisphere
+%             x and y in [700 km, 3300 km] for southern hemisphere
+%
+%   The ranges are 100 km more restrictive than for mgrs_fwd.
+%
+%   UTMUPS_FWD checks its arguments and requires that lat in [-90deg,90deg]
+%   and lon in [-540deg,540deg] and that (x,y) lie in the limits given
+%   above.  If these conditions don't hold (x,y), gam, k are converted to
+%   NaN, zone to -4 and isnorthp to 0.
+%
+%   See also UTMUPS_INV, TRANMERC_FWD, POLARST_FWD, MGRS_FWD.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  narginchk(2, 3)
+  if nargin < 3, setzone = -1; end
+  try
+    Z = zeros(size(lat + lon + setzone));
+  catch
+    error('lat, lon, setzone have incompatible sizes')
+  end
+  lat = lat + Z; lon = lon + Z;
+  isnorth = lat >= 0;
+  zone = StandardZone(lat, lon, setzone);
+  Z = nan(size(Z));
+  x = Z; y = Z; gam = Z; k = Z;
+  utm = zone > 0;
+  [x(utm), y(utm), gam(utm), k(utm)] = ...
+      utm_fwd(zone(utm), isnorth(utm), lat(utm), lon(utm));
+  ups = zone == 0;
+  [x(ups), y(ups), gam(ups), k(ups)] = ...
+      ups_fwd(isnorth(ups), lat(ups), lon(ups));
+  zone(isnan(x)) = -4; isnorth(isnan(x)) = false;
+end
+
+function [x, y, gam, k] = utm_fwd(zone, isnorth, lat, lon)
+%UTM_FWD  Forward UTM projection
+
+  lon0 = -183 + 6 * floor(zone); lat0 = 0;
+  bad = ~(abs(mod(lon - lon0 + 180, 360) - 180) <= 60);
+  fe = 5e5; fn = 100e5 * (1-isnorth); k0 = 0.9996;
+  [x, y, gam, k] = tranmerc_fwd(lat0, lon0, lat, lon);
+  x = x * k0; y = y * k0; k = k * k0;
+  bad = bad | ~(abs(x) <= 5e5 & y >= -91e5 & y <= 96e5);
+  x = x + fe; y = y + fn;
+  x(bad) = nan; y(bad) = nan; gam(bad) = nan; k(bad) = nan;
+end
+
+function [x, y, gam, k] = ups_fwd(isnorth, lat, lon)
+%UPS_FWD  Forward UPS projection
+
+  fe = 20e5; fn = 20e5; k0 = 0.994;
+  [x, y, gam, k] = polarst_fwd(isnorth, lat, lon);
+  x = x * k0; y = y * k0; k = k * k0;
+  lim = (13 - 5 * isnorth) * 1e5;
+  bad = ~(abs(x) <= lim & abs(y) <= lim);
+  x = x + fe; y = y + fn;
+  x(bad) = nan; y(bad) = nan; gam(bad) = nan; k(bad) = nan;
+end
+
+function zone = StandardZone(lat, lon, setzone)
+  INVALID = -4;
+  UTM = -2;
+  MINZONE = 0;
+  MAXZONE = 60;
+  UPS = 0;
+  zone = floor(setzone) + zeros(size(lat));
+  zone(~(zone >= INVALID & zone <= MAXZONE)) = INVALID;
+  g = zone < MINZONE & zone ~= INVALID;
+  c = abs(lat) <= 90 & abs(lon) <= 540;
+  zone(g & ~c) = INVALID;
+  g = g & c;
+  c = zone == UTM | (lat >= -80 & lat < 84);
+  u = g & c;
+  ilon = mod(floor(lon(u)) + 180, 360) - 180;
+  z = floor((ilon + 186) / 6);
+  % Norway exception
+  exception = z == 31 & floor(lat(u) / 8) == 7 & ilon >= 3;
+  z(exception) = 32;
+  % Svalbard exception
+  exception = lat(u) >= 72 & ilon >= 0 & ilon < 42;
+  z(exception) = 2 * floor((ilon(exception) + 183)/12) + 1;
+  zone(u) = z;
+  zone(g & ~c) = UPS;
+end
diff --git a/matlab/geographiclib/utmups_inv.m b/matlab/geographiclib/utmups_inv.m
new file mode 100644
index 0000000..8a5692e
--- /dev/null
+++ b/matlab/geographiclib/utmups_inv.m
@@ -0,0 +1,83 @@
+function [lat, lon, gam, k] = utmups_inv(x, y, zone, isnorth)
+%UTMUPS_INV  Convert from UTM/UPS system
+%
+%   [lat, lon] = UTMUPS_INV(x, y, zone, isnorth)
+%   [lat, lon, gam, k] = UTMUPS_INV(x, y, zone, isnorth)
+%
+%   convert to the UTM/UPS system to geographical coordinates, (lat,lon).
+%   The input is (x,y) = (easting,northing), the zone which is either the
+%   UTM zone or 0 for UPS , and a hemisphere selector, isnorth (0 for the
+%   southern hemisphere, 1 for the northern).  x, y, zone, and isnorth can
+%   be scalars or arrays of equal size.  The forward operation is performed
+%   by utmups_fwd.
+%
+%   gam and k give metric properties of the projection at (lat,lon); gam is
+%   the meridian convergence at the point and k is the scale.
+%
+%   lat, lon, gam are in degrees.  The projected coordinates x, y are in
+%   meters.  k is dimensionless.
+%
+%   The argument zone has the following meanings
+%        0, use UPS
+%        [1,60], use the corresponding UTM zone
+%       -4, an undefined zone
+%
+%   The allowed values of (x,y) are
+%        UTM: x in [0 km, 1000 km]
+%             y in [0 km, 9600 km] for northern hemisphere
+%             y in [900 km, 10000 km] for southern hemisphere
+%        UPS: x and y in [1200 km, 2800 km] for northern hemisphere
+%             x and y in [700 km, 3300 km] for southern hemisphere
+%
+%   UTMUPS_INV checks that (x,y) lie in the limits given above.  If these
+%   conditions don't hold (lat,lon), gam, k are converted to NaN.
+%
+%   See also UTMUPS_FWD, TRANMERC_INV, POLARST_INV, MGRS_INV.
+
+% Copyright (c) Charles Karney (2015) <charles at karney.com>.
+%
+% This file was distributed with GeographicLib 1.42.
+
+  narginchk(4, 4)
+  try
+    Z = zeros(size(x + y + zone + isnorth));
+  catch
+    error('x, y, zone, isnorth have incompatible sizes')
+  end
+  x = x + Z; y = y + Z;
+  zone = floor(zone) + Z; isnorth = logical(isnorth + Z);
+  Z = nan(size(Z));
+  lat = Z; lon = Z; gam = Z; k = Z;
+  utm = zone > 0 & zone <= 60;
+  [lat(utm), lon(utm), gam(utm), k(utm)] = ...
+      utm_inv(zone(utm), isnorth(utm), x(utm), y(utm));
+  ups = zone == 0;
+  [lat(ups), lon(ups), gam(ups), k(ups)] = ...
+      ups_inv(isnorth(ups), x(ups), y(ups));
+end
+
+function [lat, lon, gam, k] = utm_inv(zone, isnorth, x, y)
+%UTM_INV  Inverse UTM projection
+
+  lon0 = -183 + 6 * floor(zone); lat0 = 0;
+  fe = 5e5; fn = 100e5 * (1-isnorth); k0 = 0.9996;
+  x = x - fe; y = y - fn;
+  bad = ~(abs(x) <= 5e5 & y >= -91e5 & y <= 96e5);
+  x = x / k0; y = y / k0;
+  [lat, lon, gam, k] = tranmerc_inv(lat0, lon0, x, y);
+  k = k * k0;
+  lat(bad) = nan; lon(bad) = nan; gam(bad) = nan; k(bad) = nan;
+end
+
+function [lat, lon, gam, k] = ups_inv(isnorth, x, y)
+%UPS_INV  Inverse UPS projection
+
+  fe = 20e5; fn = 20e5; k0 = 0.994;
+  x = x - fe; y = y - fn;
+  lim = (13 - 5 * isnorth) * 1e5;
+  bad = ~(abs(x) <= lim & abs(y) <= lim);
+  x = x / k0; y = y / k0;
+  [lat, lon, gam, k] = polarst_inv(isnorth, x, y);
+  k = k * k0;
+  lat(bad) = nan; lon(bad) = nan; gam(bad) = nan; k(bad) = nan;
+end
diff --git a/matlab/geoidheight.m b/matlab/geoidheight.m
deleted file mode 100644
index 7068c14..0000000
--- a/matlab/geoidheight.m
+++ /dev/null
@@ -1,38 +0,0 @@
-function geoidheight(~, ~, ~)
-%geoidheight  Compute geoid height
-%
-%   CAUTION: THIS MAY CAUSE MATLAB TO CRASH!!  This occurs when the interface
-%   is compiled with Visual Studio 2008.
-%
-%   [height, gradient] = geoidheight(latlong)
-%   [height, gradient] = geoidheight(latlong, geoidname)
-%   [height, gradient] = geoidheight(latlong, geoidname, geoiddir)
-%
-%   latlong is an M x 2 matrix
-%       latitude = latlong(:,1) in degrees
-%       longitude = latlong(:,2) in degrees
-%   geoidname is the name of the geoid; choices are (default egm96-5)
-%       egm84-30  egm84-15
-%       egm96-15  egm96-5
-%       egm2008-5 egm2008-2_5 egm2008-1
-%   geoiddir is the directory containing the geoid models (default empty
-%       string meaning system default)
-%
-%   height is an M x 1 matrix
-%       geoidheight = height(:,1) height of geoid in meters
-%   gradient is the gradient of the geoid height
-%       gradn = gradient(:,1) gradient of height in northerly direction
-%       grade = gradient(:,2) gradient of height in easterly direction
-%
-% This is an interface to the GeographicLib C++ routine
-%     Geoid::operator()
-% See the documentation on this function for more information:
-% http://geographiclib.sf.net/html/classGeographicLib_1_1Geoid.html
-  error('Error: executing .m file instead of compiled routine');
-end
-% geoidheight.m
-% Matlab .m file for looking up geoid heights
-%
-% Copyright (c) Charles Karney (2010-2011) <charles at karney.com> and licensed
-% under the MIT/X11 License.  For more information, see
-% http://geographiclib.sourceforge.net/
diff --git a/matlab/localcartesianforward.m b/matlab/localcartesianforward.m
deleted file mode 100644
index 09415b1..0000000
--- a/matlab/localcartesianforward.m
+++ /dev/null
@@ -1,41 +0,0 @@
-function localcartesianforward(~, ~, ~, ~)
-%localcartesianforward  Convert geographic coordinates to local cartesian
-%
-%   [cartesian, rot] = localcartesianforward(origin, geodetic)
-%   [cartesian, rot] = localcartesianforward(origin, geodetic, a, f)
-%
-%   origin is a 1 x 3 or 1 x 2 matrix
-%       lat0 = origin(1,1) in degrees
-%       lon0 = origin(1,2) in degrees
-%       h0 = origin(1,3) in meters (default 0 m)
-%   geodetic is an M x 3 or M x 2 matrix of geodetic coordinates
-%       lat = geodetic(:,1) in degrees
-%       lon = geodetic(:,2) in degrees
-%       h = geodetic(:,3) in meters (default 0 m)
-%
-%   cartesian is an M x 3 matrix of local cartesian coordinates
-%       x = cartesian(:,1) in meters
-%       y = cartesian(:,2) in meters
-%       z = cartesian(:,3) in meters
-%   rot is an M x 9 matrix
-%       M = rot(:,1:9) rotation matrix in row major order.  Pre-multiplying
-%           a unit vector in local cartesian coordinates at (lat, lon, h)
-%           by M transforms the vector to local cartesian coordinates at
-%           (lat0, lon0, h0)
-%
-%   a = major radius (meters)
-%   f = flattening (0 means a sphere)
-%   If a and f are omitted, the WGS84 values are used.
-%
-% This is an interface to the GeographicLib C++ routine
-%     LocalCartesian::Forward
-% See the documentation on this function for more information:
-% http://geographiclib.sf.net/html/classGeographicLib_1_1LocalCartesian.html
-  error('Error: executing .m file instead of compiled routine');
-end
-% localcartesianforward.m
-% Matlab .m file for geographic to local cartesian conversions
-%
-% Copyright (c) Charles Karney (2011) <charles at karney.com> and licensed under
-% the MIT/X11 License.  For more information, see
-% http://geographiclib.sourceforge.net/
diff --git a/matlab/localcartesianreverse.m b/matlab/localcartesianreverse.m
deleted file mode 100644
index edba383..0000000
--- a/matlab/localcartesianreverse.m
+++ /dev/null
@@ -1,41 +0,0 @@
-function localcartesianreverse(~, ~, ~, ~)
-%localcartesianreverse  Convert local cartesian coordinates to geographic
-%
-%   [geodetic, rot] = localcartesianreverse(origin, cartesian)
-%   [geodetic, rot] = localcartesianreverse(origin, cartesian, a, f)
-%
-%   origin is a 1 x 3 or 1 x 2 matrix
-%       lat0 = origin(1,1) in degrees
-%       lon0 = origin(1,2) in degrees
-%       h0 = origin(1,3) in meters (default 0 m)
-%   cartesian is an M x 3 matrix of local cartesian coordinates
-%       x = cartesian(:,1) in meters
-%       y = cartesian(:,2) in meters
-%       z = cartesian(:,3) in meters
-%
-%   geodetic is an M x 3 matrix of geodetic coordinates
-%       lat = geodetic(:,1) in degrees
-%       lon = geodetic(:,2) in degrees
-%       h = geodetic(:,3) in meters
-%   rot is an M x 9 matrix
-%       M = rot(:,1:9) rotation matrix in row major order.  Pre-multiplying
-%           a unit vector in local cartesian coordinates at (lat0, lon0, h0)
-%           by the transpose of M transforms the vector to local cartesian
-%           coordinates at (lat, lon, h).
-%
-%   a = major radius (meters)
-%   f = flattening (0 means a sphere)
-%   If a and f are omitted, the WGS84 values are used.
-%
-% This is an interface to the GeographicLib C++ routine
-%     LocalCartesian::Reverse
-% See the documentation on this function for more information:
-% http://geographiclib.sf.net/html/classGeographicLib_1_1LocalCartesian.html
-  error('Error: executing .m file instead of compiled routine');
-end
-% localcartesianreverse.m
-% Matlab .m file for local cartesian to geographic conversions
-%
-% Copyright (c) Charles Karney (2011) <charles at karney.com> and licensed under
-% the MIT/X11 License.  For more information, see
-% http://geographiclib.sourceforge.net/
diff --git a/matlab/mgrsforward.m b/matlab/mgrsforward.m
deleted file mode 100644
index 2656cc8..0000000
--- a/matlab/mgrsforward.m
+++ /dev/null
@@ -1,31 +0,0 @@
-function mgrsforward(~, ~)
-%mgrsforward  Convert UTM/UPS coordinates to MGRS
-%
-%   mgrs = mgrsforward(utmups)
-%   mgrs = mgrsforward(utmups, prec)
-%
-%   utmups is an M x 4 matrix
-%       easting = utmups(:,1) in meters
-%       northing = utmups(:,2) in meters
-%       zone = utmups(:,3)
-%       hemi = utmups(:,4)
-%
-%   zone = 0 for UPS, zone = [1,60] for UTM
-%   hemi = 0 for southern hemisphere, hemi = 1 for northern hemisphere
-%   prec = half the number of trailing digits in the MGRS string
-%          (default 5)
-%
-%   mgrs is a M x 1 cell array of MGRS strings.
-%
-% This is an interface to the GeographicLib C++ routine
-%     MGRS::Forward
-% See the documentation on this function for more information:
-% http://geographiclib.sf.net/html/classGeographicLib_1_1MGRS.html
-  error('Error: executing .m file instead of compiled routine');
-end
-% mgrsforward.m
-% Matlab .m file for UTM/UPS to MGRS conversions
-%
-% Copyright (c) Charles Karney (2010-2011) <charles at karney.com> and licensed
-% under the MIT/X11 License.  For more information, see
-% http://geographiclib.sourceforge.net/
diff --git a/matlab/polygonarea.m b/matlab/polygonarea.m
deleted file mode 100644
index 036a962..0000000
--- a/matlab/polygonarea.m
+++ /dev/null
@@ -1,47 +0,0 @@
-function polygonarea(~, ~, ~)
-%polygonarea  Compute area of a geodesic polygon
-%
-%   [area, perimeter] = polygonarea(latlong)
-%   [area, perimeter] = polygonarea(latlong, a, f)
-%
-%   latlong is an M x 2 matrix
-%       latitude of vertices = latlong(:,1) in degrees
-%       longitude of vertices = latlong(:,2) in degrees
-%
-%   area is the area in meters^2
-%   perimeter is the perimeter in meters
-%
-%   a = major radius (meters)
-%   f = flattening (0 means a sphere)
-%   If a and f are omitted, the WGS84 values are used.
-%
-% Only simple polygons (which do not intersect themselves) are supported.
-% There is no need to "close" the polygon.  Counter-clockwise traversal
-% counts as a positive area.  A polygon may encircle one or both poles.
-% The total area of the WGS84 ellipsoid is given by
-%   8 * polygonarea([ 0 0; 0 90; 90 0 ])
-%
-% The algorithm used in this function is given in
-%
-%     C. F. F. Karney, Algorithms for geodesics,
-%     J. Geodesy 87, 43-55 (2013);
-%     https://dx.doi.org/10.1007/s00190-012-0578-z
-%     Addenda: http://geographiclib.sf.net/geod-addenda.html
-%
-% This is an interface to the GeographicLib C++ class
-%     Geodesic::PolygonArea
-% See the documentation on this function for more information:
-% http://geographiclib.sf.net/html/classGeographicLib_1_1PolygonArea
-%
-% A native MATLAB implementation is available as GEODAREA.
-%
-% See also GEODAREA.
-
-  error('Error: executing .m file instead of compiled routine');
-end
-% polygonarea.m
-% Matlab .m file for finding polygon areas
-%
-% Copyright (c) Charles Karney (2011) <charles at karney.com> and licensed under
-% the MIT/X11 License.  For more information, see
-% http://geographiclib.sourceforge.net/
diff --git a/matlab/private/C1pf.m b/matlab/private/C1pf.m
deleted file mode 100644
index 3f052ce..0000000
--- a/matlab/private/C1pf.m
+++ /dev/null
@@ -1,22 +0,0 @@
-function c = C1pf(epsi)
-%C1PF  Evaluate C'_{1,k}
-%
-%   C1P = C1PF(EPSI) evaluates C'_{1,l} using Eq. (21).  EPSI is an
-%   K x 1 array and C1 is a K x 6 array.
-
-  nC1p = 6;
-  c = zeros(length(epsi), nC1p);
-  eps2 = epsi.^2;
-  d = epsi;
-  c(:,1) = d.*(eps2.*(205*eps2-432)+768)/1536;
-  d = d.*epsi;
-  c(:,2) = d.*(eps2.*(4005*eps2-4736)+3840)/12288;
-  d = d.*epsi;
-  c(:,3) = d.*(116-225*eps2)/384;
-  d = d.*epsi;
-  c(:,4) = d.*(2695-7173*eps2)/7680;
-  d = d.*epsi;
-  c(:,5) = 3467*d/7680;
-  d = d.*epsi;
-  c(:,6) = 38081*d/61440;
-end
diff --git a/matlab/private/SinCosNorm.m b/matlab/private/SinCosNorm.m
deleted file mode 100644
index 9e53341..0000000
--- a/matlab/private/SinCosNorm.m
+++ /dev/null
@@ -1,10 +0,0 @@
-function [sinx, cosx] = SinCosNorm(sinx, cosx)
-%SINCOSNORM  Normalize sinx and cosx
-%
-%   [SINX, COSX] = SINCOSNORM(SINX, COSX) normalize SINX and COSX so that
-%   SINX^2 + COSX^2 = 1.  SINX and COSX can be any shape.
-
-  r = hypot(sinx, cosx);
-  sinx = sinx ./ r;
-  cosx = cosx ./ r;
-end
diff --git a/matlab/private/atanhee.m b/matlab/private/atanhee.m
deleted file mode 100644
index 66c2bb3..0000000
--- a/matlab/private/atanhee.m
+++ /dev/null
@@ -1,15 +0,0 @@
-function y = atanhee(x, e2)
-%ATANHEE   atanh(e*x)/e
-%
-%   ATANHEE(X, E2) returns atanh(E*X)/E where E = SQRT(E2)
-%   E2 is a scalar; X can be any shape.
-
-  e = sqrt(abs(e2));
-  if (e2 > 0)
-    y = atanh(e * x) / e;
-  elseif (e2 < 0)
-    y = atan(e * x) / e;
-  else
-    y = x;
-  end
-end
diff --git a/matlab/private/cbrt.m b/matlab/private/cbrt.m
deleted file mode 100644
index 5c9405c..0000000
--- a/matlab/private/cbrt.m
+++ /dev/null
@@ -1,9 +0,0 @@
-function y = cbrt(x)
-%CBRT   The real cube root
-%
-%   CBRT(X) is the real cube root of X (assuming X is real).  X
-%   can be any shape.
-
-  y = abs(x).^(1/3);
-  y(x < 0) = -y(x < 0);
-end
diff --git a/matlab/private/swap.m b/matlab/private/swap.m
deleted file mode 100644
index e3b520f..0000000
--- a/matlab/private/swap.m
+++ /dev/null
@@ -1,8 +0,0 @@
-function [a, b] = swap(x, y)
-%SWAP  Swap two variables.
-%
-%   [A, B] = SWAP(X, Y) sets A to Y and B to X.
-
-  a = y;
-  b = x;
-end
diff --git a/matlab/utm_fwd.m b/matlab/utm_fwd.m
deleted file mode 100644
index cc835f8..0000000
--- a/matlab/utm_fwd.m
+++ /dev/null
@@ -1,50 +0,0 @@
-function [x, y, gam, k] = utm_fwd(zone, northp, lat, lon)
-%UTM_FWD  Forward UTM projection
-%
-%   [X, Y] = UTM_FWD(ZONE, NORTHP, LAT, LON)
-%   [X, Y, GAM, K] = UTM_FWD(ZONE, NORTHP, LAT, LON)
-%
-%   performs the forward universal transverse Mercator projection of points
-%   (LAT,LON) to (X,Y) using ZONE and NORTHP.  LAT and LON can be scalars
-%   or arrays of equal size.  ZONE should be an integer in [1,60] and
-%   NORTHP is a logical indicating whether the transformation should use
-%   the false northing for the northern (NORTHP = true) or southern (NORTHP
-%   = false) hemisphere.  The inverse projection is given by UTM_INV.
-%
-%   GAM and K give metric properties of the projection at (LAT,LON); GAM is
-%   the meridian convergence at the point and K is the scale.
-%
-%   LAT, LON, GAM are in degrees.  The projected coordinates X, Y are in
-%   meters.  K is dimensionless.
-%
-%   This implementation for the UTM projection is based on the series
-%   method described in
-%
-%     C. F. F. Karney, Transverse Mercator with an accuracy of a few
-%     nanometers, J. Geodesy 85(8), 475-485 (Aug. 2011);
-%     Addenda: http://geographiclib.sf.net/tm-addenda.html
-%
-%   This extends the series given by Krueger (1912) to sixth order in the
-%   flattening.  This is a substantially better series than that used by
-%   the MATLAB mapping toolbox.  In particular the errors in the projection
-%   are less than 5 nanometers withing 3900 km of the central meridian (and
-%   less than 1 mm within 7600 km of the central meridian).  The mapping
-%   can be continued accurately over the poles to the opposite meridian.
-%
-%   This routine depends on the MATLAB File Exchange package "Geodesics on
-%   an ellipsoid of revolution":
-%
-%     http://www.mathworks.com/matlabcentral/fileexchange/39108
-%
-%   See also GEODPROJ, UTM_INV, TRANMERC_FWD.
-
-% Copyright (c) Charles Karney (2012) <charles at karney.com>.
-%
-% This file was distributed with GeographicLib 1.29.
-
-  if nargin < 4, error('Too few input arguments'), end
-  lon0 = -183 + 6 * zone; lat0 = 0;
-  fe = 500e3; fn = cvmgt(0,10000e3,logical(northp)); k0 = 0.9996;
-  [x, y, gam, k] = tranmerc_fwd(lat0, lon0, lat, lon);
-  x = x * k0 + fe; y = y * k0 + fn; k = k * k0;
-end
diff --git a/matlab/utm_inv.m b/matlab/utm_inv.m
deleted file mode 100644
index 23ad351..0000000
--- a/matlab/utm_inv.m
+++ /dev/null
@@ -1,51 +0,0 @@
-function [lat, lon, gam, k] = utm_inv(zone, northp, x, y)
-%UTM_INV  Forward transverse Mercator projection
-%
-%   [LAT, LON] = UTM_INV(ZONE, NORTHP, X, Y)
-%   [LAT, LON, GAM, K] = UTM_INV(ZONE, NORTHP, X, Y)
-%
-%   performs the inverse universal transverse Mercator projection of points
-%   (X,Y) to (LAT,LON) using ZONE and NORTHP.  X and Y can be scalars or
-%   arrays of equal size.  ZONE should be an integer in [1,60] and NORTHP
-%   is a logical indicating whether the transformation should use the false
-%   northing for the northern (NORTHP = true) or southern (NORTHP = false)
-%   hemisphere.  The forward projection is given by UTM_FWD.
-%
-%   GAM and K give metric properties of the projection at (LAT,LON); GAM is
-%   the meridian convergence at the point and K is the scale.
-%
-%   LAT, LON, GAM are in degrees.  The projected coordinates X, Y are in
-%   meters.  K is dimensionless.
-%
-%   This implementation for the UTM projection is based on the series
-%   method described in
-%
-%     C. F. F. Karney, Transverse Mercator with an accuracy of a few
-%     nanometers, J. Geodesy 85(8), 475-485 (Aug. 2011);
-%     Addenda: http://geographiclib.sf.net/tm-addenda.html
-%
-%   This extends the series given by Krueger (1912) to sixth order in the
-%   flattening.  This is a substantially better series than that used by
-%   the MATLAB mapping toolbox.  In particular the errors in the projection
-%   are less than 5 nanometers withing 3900 km of the central meridian (and
-%   less than 1 mm within 7600 km of the central meridian).  The mapping
-%   can be continued accurately over the poles to the opposite meridian.
-%
-%   This routine depends on the MATLAB File Exchange package "Geodesics on
-%   an ellipsoid of revolution":
-%
-%     http://www.mathworks.com/matlabcentral/fileexchange/39108
-%
-%   See also GEODPROJ, UTM_FWD, TRANMERC_INV.
-
-% Copyright (c) Charles Karney (2012) <charles at karney.com>.
-%
-% This file was distributed with GeographicLib 1.29.
-
-  if nargin < 4, error('Too few input arguments'), end
-  lon0 = -183 + 6 * zone; lat0 = 0;
-  fe = 500e3; fn = cvmgt(0, 10000e3, logical(northp)); k0 = 0.9996;
-  x = (x - fe) / k0; y = (y - fn) / k0;
-  [lat, lon, gam, k] = tranmerc_inv(lat0, lon0, x, y);
-  k = k * k0;
-end
diff --git a/matlab/utmupsreverse.m b/matlab/utmupsreverse.m
deleted file mode 100644
index 4e9b52f..0000000
--- a/matlab/utmupsreverse.m
+++ /dev/null
@@ -1,33 +0,0 @@
-function utmupsreverse(~)
-%utmupsreverse  Convert UTM/UPS coordinates to geographic
-%
-%   [latlong, scale] = utmupsreverse(utmups)
-%
-%   utmups is an M x 4 matrix
-%       easting = utmups(:,1) in meters
-%       northing = utmups(:,2) in meters
-%       zone = utmups(:,3)
-%       hemi = utmups(:,4)
-%
-%   zone = 0 for UPS, zone = [1,60] for UTM
-%   hemi = 0 for southern hemisphere, hemi = 1 for northern hemisphere.
-%
-%   latlong is an M x 2 matrix
-%       latitude = latlong(:,1) in degrees
-%       longitude = latlong(:,2) in degrees
-%   scale is an M x 2 matrix
-%       gamma = scale(:,1) meridian convergence in degrees
-%       k = scale(:,2) scale
-%
-% This is an interface to the GeographicLib C++ routine
-%     UTMUPS::Reverse
-% See the documentation on this function for more information:
-% http://geographiclib.sf.net/html/classGeographicLib_1_1MGRS.html
-  error('Error: executing .m file instead of compiled routine');
-end
-% utmupsreverse.m
-% Matlab .m file for UTM/UPS to geographic conversions
-%
-% Copyright (c) Charles Karney (2010-2011) <charles at karney.com> and licensed
-% under the MIT/X11 License.  For more information, see
-% http://geographiclib.sourceforge.net/
diff --git a/missing b/missing
index cdea514..db98974 100755
--- a/missing
+++ b/missing
@@ -1,7 +1,7 @@
 #! /bin/sh
 # Common wrapper for a few potentially missing GNU programs.
 
-scriptversion=2012-06-26.16; # UTC
+scriptversion=2013-10-28.13; # UTC
 
 # Copyright (C) 1996-2013 Free Software Foundation, Inc.
 # Originally written by Fran,cois Pinard <pinard at iro.umontreal.ca>, 1996.
@@ -160,7 +160,7 @@ give_advice ()
       ;;
    autom4te*)
       echo "You might have modified some maintainer files that require"
-      echo "the 'automa4te' program to be rebuilt."
+      echo "the 'autom4te' program to be rebuilt."
       program_details 'autom4te'
       ;;
     bison*|yacc*)
diff --git a/pom.xml b/pom.xml
index df7bdb7..6b6561b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,7 +13,7 @@
 
   <groupId>com.sri.vt</groupId>
   <artifactId>geographiclib</artifactId>
-  <version>1.41-SNAPSHOT</version>
+  <version>1.42-SNAPSHOT</version>
   <packaging>majic-cmake</packaging>
   <name>GeographicLib</name>
 
@@ -53,7 +53,6 @@
             <configuration>
               <options>
                 <GEOGRAPHICLIB_LIB_TYPE>BOTH</GEOGRAPHICLIB_LIB_TYPE>
-                <MATLAB_COMPILER>OFF</MATLAB_COMPILER>
                 <GEOGRAPHICLIB_DOCUMENTATION>OFF</GEOGRAPHICLIB_DOCUMENTATION>
                 <BUILD_NETGEOGRAPHICLIB>
                   ${build.netgeographiclib}
diff --git a/python/Makefile.in b/python/Makefile.in
index 036433c..77c8569 100644
--- a/python/Makefile.in
+++ b/python/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994-2013 Free Software Foundation, Inc.
diff --git a/src/CassiniSoldner.cpp b/src/CassiniSoldner.cpp
index 0f64ae4..f00add3 100644
--- a/src/CassiniSoldner.cpp
+++ b/src/CassiniSoldner.cpp
@@ -2,7 +2,7 @@
  * \file CassiniSoldner.cpp
  * \brief Implementation for GeographicLib::CassiniSoldner class
  *
- * Copyright (c) Charles Karney (2009-2011) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2009-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  **********************************************************************/
@@ -34,7 +34,7 @@ namespace GeographicLib {
       f = _earth.Flattening();
     _sbet0 = (1 - f) * sin(phi);
     _cbet0 = abs(LatitudeOrigin()) == 90 ? 0 : cos(phi);
-    SinCosNorm(_sbet0, _cbet0);
+    Math::norm(_sbet0, _cbet0);
   }
 
   void CassiniSoldner::Forward(real lat, real lon, real& x, real& y,
@@ -43,7 +43,7 @@ namespace GeographicLib {
       return;
     real dlon = Math::AngDiff(LongitudeOrigin(), Math::AngNormalize(lon));
     real sig12, s12, azi1, azi2;
-    lat = AngRound(lat);
+    lat = Math::AngRound(lat);
     sig12 = _earth.Inverse(lat, -abs(dlon), lat, abs(dlon), s12, azi1, azi2);
     if (sig12 < 100 * tiny_)
       sig12 = s12 = 0;
diff --git a/src/DMS.cpp b/src/DMS.cpp
index 4c29543..07a5e2a 100644
--- a/src/DMS.cpp
+++ b/src/DMS.cpp
@@ -2,7 +2,7 @@
  * \file DMS.cpp
  * \brief Implementation for GeographicLib::DMS class
  *
- * Copyright (c) Charles Karney (2008-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2008-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  **********************************************************************/
@@ -42,15 +42,47 @@ namespace GeographicLib {
     replace(dmsa, "\xba", 'd');          // 0xba bare alt symbol
     replace(dmsa, "\xb4", '\'');         // 0xb4 bare acute accent
     replace(dmsa, "''", '"');            // '' -> "
+    unsigned
+      beg = 0,
+      end = unsigned(dmsa.size());
+    while (beg < end && isspace(dmsa[beg]))
+      ++beg;
+    while (beg < end && isspace(dmsa[end - 1]))
+      --end;
+    unsigned bega = beg;
+    if (end > bega && Utility::lookup(hemispheres_, dmsa[bega]) >= 0)
+      ++bega;
+    if (end > bega && Utility::lookup(signs_, dmsa[bega]) >= 0)
+      ++bega;
+    string::size_type p = dmsa.find_first_of(signs_, bega);
+    flag ind1 = NONE;
+    real v = InternalDecode(dmsa.substr(beg,
+                                        (p == string::npos ? end : p) - beg),
+                            ind1);
+    if (p == string::npos)
+      ind = ind1;
+    else {
+      flag ind2 = NONE;
+      v += InternalDecode(dmsa.substr(p, end - p), ind2);
+      if (ind2 == NONE)
+        ind = ind1;
+      else if (ind1 == NONE || ind1 == ind2)
+        ind = ind2;
+      else
+        throw GeographicErr("Incompatible hemisphere specifies in " +
+                            dmsa.substr(beg, p - beg) + " and " +
+                            dmsa.substr(p, end - p));
+    }
+    return v;
+  }
+
+  Math::real DMS::InternalDecode(const std::string& dmsa, flag& ind) {
+    string errormsg;
     do {                       // Executed once (provides the ability to break)
       int sign = 1;
       unsigned
         beg = 0,
         end = unsigned(dmsa.size());
-      while (beg < end && isspace(dmsa[beg]))
-        ++beg;
-      while (beg < end && isspace(dmsa[end - 1]))
-        --end;
       flag ind1 = NONE;
       int k = -1;
       if (end > beg && (k = Utility::lookup(hemispheres_, dmsa[beg])) >= 0) {
@@ -310,24 +342,25 @@ namespace GeographicLib {
     case DEGREE:
       if (ind != NONE)
         s << setw(1 + min(int(ind), 2) + prec + (prec ? 1 : 0));
-      s << setprecision(prec) << pieces[0];
+      s << Utility::str(pieces[0], prec);
       // Don't include degree designator (d) if it is the trailing component.
       break;
     default:
       if (ind != NONE)
         s << setw(1 + min(int(ind), 2));
-      s << setprecision(0) << pieces[0]
+      s << int(pieces[0])
         << (dmssep ? dmssep : char(tolower(dmsindicators_[0])));
       switch (trailing) {
       case MINUTE:
-        s << setw(2 + prec + (prec ? 1 : 0)) << setprecision(prec) << pieces[1];
+        s << setw(2 + prec + (prec ? 1 : 0)) << Utility::str(pieces[1], prec);
         if (!dmssep)
           s << char(tolower(dmsindicators_[1]));
         break;
       case SECOND:
         s << setw(2)
-          << pieces[1] << (dmssep ? dmssep : char(tolower(dmsindicators_[1])))
-          << setw(2 + prec + (prec ? 1 : 0)) << setprecision(prec) << pieces[2];
+          << int(pieces[1])
+          << (dmssep ? dmssep : char(tolower(dmsindicators_[1])))
+          << setw(2 + prec + (prec ? 1 : 0)) << Utility::str(pieces[2], prec);
         if (!dmssep)
           s << char(tolower(dmsindicators_[2]));
         break;
diff --git a/src/Ellipsoid.cpp b/src/Ellipsoid.cpp
index fef90c5..2734170 100644
--- a/src/Ellipsoid.cpp
+++ b/src/Ellipsoid.cpp
@@ -2,7 +2,7 @@
  * \file Ellipsoid.cpp
  * \brief Implementation for GeographicLib::Ellipsoid class
  *
- * Copyright (c) Charles Karney (2012-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2012-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  **********************************************************************/
@@ -20,7 +20,7 @@ namespace GeographicLib {
     , _f1(1 - _f)
     , _f12(Math::sq(_f1))
     , _e2(_f * (2 - _f))
-    , _e(sqrt(abs(_e2)))
+    , _es((_f < 0 ? -1 : 1) * sqrt(abs(_e2)))
     , _e12(_e2 / (1 - _e2))
     , _n(_f / (2  - _f))
     , _b(_a * _f1)
@@ -46,16 +46,16 @@ namespace GeographicLib {
   }
 
   Math::real Ellipsoid::ParametricLatitude(real phi) const
-  { return atand(_f1 * tand(phi)); }
+  { return Math::atand(_f1 * Math::tand(phi)); }
 
   Math::real Ellipsoid::InverseParametricLatitude(real beta) const
-  { return atand(tand(beta) / _f1); }
+  { return Math::atand(Math::tand(beta) / _f1); }
 
   Math::real Ellipsoid::GeocentricLatitude(real phi) const
-  { return atand(_f12 * tand(phi)); }
+  { return Math::atand(_f12 * Math::tand(phi)); }
 
   Math::real Ellipsoid::InverseGeocentricLatitude(real theta) const
-  { return atand(tand(theta) / _f12); }
+  { return Math::atand(Math::tand(theta) / _f12); }
 
   Math::real Ellipsoid::RectifyingLatitude(real phi) const {
     return abs(phi) == 90 ? phi:
@@ -70,33 +70,33 @@ namespace GeographicLib {
   }
 
   Math::real Ellipsoid::AuthalicLatitude(real phi) const
-  { return atand(_au.txif(tand(phi))); }
+  { return Math::atand(_au.txif(Math::tand(phi))); }
 
   Math::real Ellipsoid::InverseAuthalicLatitude(real xi) const
-  { return atand(_au.tphif(tand(xi))); }
+  { return Math::atand(_au.tphif(Math::tand(xi))); }
 
   Math::real Ellipsoid::ConformalLatitude(real phi) const
-  { return atand(_tm.taupf(tand(phi))); }
+  { return Math::atand(Math::taupf(Math::tand(phi), _es)); }
 
   Math::real Ellipsoid::InverseConformalLatitude(real chi) const
-  { return atand(_tm.tauf(tand(chi))); }
+  { return Math::atand(Math::tauf(Math::tand(chi), _es)); }
 
   Math::real Ellipsoid::IsometricLatitude(real phi) const
-  { return Math::asinh(_tm.taupf(tand(phi))) / Math::degree(); }
+  { return Math::asinh(Math::taupf(Math::tand(phi), _es)) / Math::degree(); }
 
   Math::real Ellipsoid::InverseIsometricLatitude(real psi) const
-  { return atand(_tm.tauf(sinh(psi * Math::degree()))); }
+  { return Math::atand(Math::tauf(sinh(psi * Math::degree()), _es)); }
 
   Math::real Ellipsoid::CircleRadius(real phi) const {
     return abs(phi) == 90 ? 0 :
       // a * cos(beta)
-      _a / Math::hypot(real(1), _f1 * tand(phi));
+      _a / Math::hypot(real(1), _f1 * Math::tand(phi));
   }
 
   Math::real Ellipsoid::CircleHeight(real phi) const {
-    real tbeta = _f1 * tand(phi);
+    real tbeta = _f1 * Math::tand(phi);
     // b * sin(beta)
-    return _b * tbeta / Math::hypot(real(1), _f1 * tand(phi));
+    return _b * tbeta / Math::hypot(real(1), _f1 * Math::tand(phi));
   }
 
   Math::real Ellipsoid::MeridianDistance(real phi) const
diff --git a/src/GeoCoords.cpp b/src/GeoCoords.cpp
index baf1b6e..e0ce6f8 100644
--- a/src/GeoCoords.cpp
+++ b/src/GeoCoords.cpp
@@ -10,6 +10,7 @@
 #include <GeographicLib/GeoCoords.hpp>
 #include <GeographicLib/MGRS.hpp>
 #include <GeographicLib/DMS.hpp>
+#include <GeographicLib/Utility.hpp>
 
 namespace GeographicLib {
 
@@ -109,13 +110,13 @@ namespace GeographicLib {
     real scale = prec < 0 ? pow(real(10), -prec) : real(1);
     os << UTMUPS::EncodeZone(zone, northp, abbrev) << fixed << setfill('0');
     if (Math::isfinite(easting)) {
-      os << " " << setprecision(max(0, prec)) << easting / scale;
+      os << " " << Utility::str(easting / scale, max(0, prec));
       if (prec < 0 && abs(easting / scale) > real(0.5))
         os << setw(-prec) << 0;
     } else
       os << " nan";
     if (Math::isfinite(northing)) {
-      os << " " << setprecision(max(0, prec)) << northing / scale;
+      os << " " << Utility::str(northing / scale, max(0, prec));
       if (prec < 0 && abs(northing / scale) > real(0.5))
         os << setw(-prec) << 0;
     } else
diff --git a/src/Geocentric.cpp b/src/Geocentric.cpp
index 8eda571..5120b4f 100644
--- a/src/Geocentric.cpp
+++ b/src/Geocentric.cpp
@@ -2,7 +2,7 @@
  * \file Geocentric.cpp
  * \brief Implementation for GeographicLib::Geocentric class
  *
- * Copyright (c) Charles Karney (2008-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2008-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  **********************************************************************/
@@ -45,7 +45,7 @@ namespace GeographicLib {
       n = _a/sqrt(1 - _e2 * Math::sq(sphi)),
       slam = lon == -180 ? 0 : sin(lam),
       clam = abs(lon) == 90 ? 0 : cos(lam);
-    Z = ( _e2m * n + h) * sphi;
+    Z = (_e2m * n + h) * sphi;
     X = (n + h) * cphi;
     Y = X * slam;
     X *= clam;
@@ -152,8 +152,8 @@ namespace GeographicLib {
       }
     }
     lat = atan2(sphi, cphi) / Math::degree();
-    // Negative signs return lon in [-180, 180).
-    lon = -atan2(-slam, clam) / Math::degree();
+    // Negative signs return lon in [-180, 180).  0- converts -0 to +0.
+    lon = Math::atan2d(slam, clam);
     if (M)
       Rotation(sphi, cphi, slam, clam, M);
   }
diff --git a/src/Geodesic.cpp b/src/Geodesic.cpp
index d62e518..0a0bcf9 100644
--- a/src/Geodesic.cpp
+++ b/src/Geodesic.cpp
@@ -2,7 +2,7 @@
  * \file Geodesic.cpp
  * \brief Implementation for GeographicLib::Geodesic class
  *
- * Copyright (c) Charles Karney (2009-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2009-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  *
@@ -62,9 +62,8 @@ namespace GeographicLib {
     , _n(_f / ( 2 - _f))
     , _b(_a * _f1)
     , _c2((Math::sq(_a) + Math::sq(_b) *
-           (_e2 == 0 ? 1 :
-            (_e2 > 0 ? Math::atanh(sqrt(_e2)) : atan(sqrt(-_e2))) /
-            sqrt(abs(_e2))))/2) // authalic radius squared
+           Math::eatanhe(real(1), (_f < 0 ? -1 : 1) * sqrt(abs(_e2))) / _e2)
+          / 2) // authalic radius squared
       // The sig12 threshold for "really short".  Using the auxiliary sphere
       // solution with dnm computed at (bet1 + bet2) / 2, the relative error in
       // the azimuth consistency check is sig12^2 * abs(f) * min(1, 1-f/2) / 2.
@@ -146,13 +145,13 @@ namespace GeographicLib {
     real lon12 = Math::AngDiff(Math::AngNormalize(lon1),
                                Math::AngNormalize(lon2));
     // If very close to being on the same half-meridian, then make it so.
-    lon12 = AngRound(lon12);
+    lon12 = Math::AngRound(lon12);
     // Make longitude difference positive.
     int lonsign = lon12 >= 0 ? 1 : -1;
     lon12 *= lonsign;
     // If really close to the equator, treat as on equator.
-    lat1 = AngRound(lat1);
-    lat2 = AngRound(lat2);
+    lat1 = Math::AngRound(lat1);
+    lat2 = Math::AngRound(lat2);
     // Swap points so that point with higher (abs) latitude is point 1
     int swapp = abs(lat1) >= abs(lat2) ? 1 : -1;
     if (swapp < 0) {
@@ -181,13 +180,13 @@ namespace GeographicLib {
     // Ensure cbet1 = +epsilon at poles
     sbet1 = _f1 * sin(phi);
     cbet1 = lat1 == -90 ? tiny_ : cos(phi);
-    SinCosNorm(sbet1, cbet1);
+    Math::norm(sbet1, cbet1);
 
     phi = lat2 * Math::degree();
     // Ensure cbet2 = +epsilon at poles
     sbet2 = _f1 * sin(phi);
     cbet2 = abs(lat2) == 90 ? tiny_ : cos(phi);
-    SinCosNorm(sbet2, cbet2);
+    Math::norm(sbet2, cbet2);
 
     // If cbet1 < -sbet1, then cbet2 - cbet1 is a sensitive measure of the
     // |bet1| - |bet2|.  Alternatively (cbet1 >= -sbet1), abs(sbet2) + sbet1 is
@@ -340,7 +339,7 @@ namespace GeographicLib {
             if (nsalp1 > 0 && abs(dalp1) < Math::pi()) {
               calp1 = calp1 * cdalp1 - salp1 * sdalp1;
               salp1 = nsalp1;
-              SinCosNorm(salp1, calp1);
+              Math::norm(salp1, calp1);
               // In some regimes we don't get quadratic convergence because
               // slope -> 0.  So use convergence conditions based on epsilon
               // instead of sqrt(epsilon).
@@ -358,7 +357,7 @@ namespace GeographicLib {
           // WGS84 and random input: mean = 4.74, sd = 0.99
           salp1 = (salp1a + salp1b)/2;
           calp1 = (calp1a + calp1b)/2;
-          SinCosNorm(salp1, calp1);
+          Math::norm(salp1, calp1);
           tripn = false;
           tripb = (abs(salp1a - salp1) + (calp1a - calp1) < tolb_ ||
                    abs(salp1 - salp1b) + (calp1 - calp1b) < tolb_);
@@ -397,8 +396,8 @@ namespace GeographicLib {
           eps = k2 / (2 * (1 + sqrt(1 + k2)) + k2),
           // Multiplier = a^2 * e^2 * cos(alpha0) * sin(alpha0).
           A4 = Math::sq(_a) * calp0 * salp0 * _e2;
-        SinCosNorm(ssig1, csig1);
-        SinCosNorm(ssig2, csig2);
+        Math::norm(ssig1, csig1);
+        Math::norm(ssig2, csig2);
         real C4a[nC4_];
         C4f(eps, C4a);
         real
@@ -454,8 +453,8 @@ namespace GeographicLib {
 
     if (outmask & AZIMUTH) {
       // minus signs give range [-180, 180). 0- converts -0 to +0.
-      azi1 = 0 - atan2(-salp1, calp1) / Math::degree();
-      azi2 = 0 - atan2(-salp2, calp2) / Math::degree();
+      azi1 = Math::atan2d(salp1, calp1);
+      azi2 = Math::atan2d(salp2, calp2);
     }
 
     // Returned value in [0, 180]
@@ -611,7 +610,7 @@ namespace GeographicLib {
       salp2 = cbet1 * somg12;
       calp2 = sbet12 - cbet1 * sbet2 *
         (comg12 >= 0 ? Math::sq(somg12) / (1 + comg12) : 1 - comg12);
-      SinCosNorm(salp2, calp2);
+      Math::norm(salp2, calp2);
       // Set return value
       sig12 = atan2(ssig12, csig12);
     } else if (abs(_n) > real(0.1) || // Skip astroid calc if too eccentric
@@ -712,7 +711,7 @@ namespace GeographicLib {
     }
     // Sanity check on starting guess.  Backwards check allows NaN through.
     if (!(salp1 <= 0))
-      SinCosNorm(salp1, calp1);
+      Math::norm(salp1, calp1);
     else {
       salp1 = 1; calp1 = 0;
     }
@@ -746,8 +745,8 @@ namespace GeographicLib {
     // tan(omg1) = sin(alp0) * tan(sig1) = tan(omg1)=tan(alp1)*sin(bet1)
     ssig1 = sbet1; somg1 = salp0 * sbet1;
     csig1 = comg1 = calp1 * cbet1;
-    SinCosNorm(ssig1, csig1);
-    // SinCosNorm(somg1, comg1); -- don't need to normalize!
+    Math::norm(ssig1, csig1);
+    // Math::norm(somg1, comg1); -- don't need to normalize!
 
     // Enforce symmetries in the case abs(bet2) = -bet1.  Need to be careful
     // about this case, since this can yield singularities in the Newton
@@ -768,8 +767,8 @@ namespace GeographicLib {
     // tan(omg2) = sin(alp0) * tan(sig2).
     ssig2 = sbet2; somg2 = salp0 * sbet2;
     csig2 = comg2 = calp2 * cbet2;
-    SinCosNorm(ssig2, csig2);
-    // SinCosNorm(somg2, comg2); -- don't need to normalize!
+    Math::norm(ssig2, csig2);
+    // Math::norm(somg2, comg2); -- don't need to normalize!
 
     // sig12 = sig2 - sig1, limit to [0, pi]
     sig12 = atan2(max(csig1 * ssig2 - ssig1 * csig2, real(0)),
diff --git a/src/GeodesicExact.cpp b/src/GeodesicExact.cpp
index 3912a24..213911c 100644
--- a/src/GeodesicExact.cpp
+++ b/src/GeodesicExact.cpp
@@ -2,7 +2,7 @@
  * \file GeodesicExact.cpp
  * \brief Implementation for GeographicLib::GeodesicExact class
  *
- * Copyright (c) Charles Karney (2012-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2012-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  *
@@ -61,9 +61,15 @@ namespace GeographicLib {
     , _ep2(_e2 / Math::sq(_f1))       // e2 / (1 - e2)
     , _n(_f / ( 2 - _f))
     , _b(_a * _f1)
+      // The Geodesic class substitutes atanh(sqrt(e2)) for asinh(sqrt(ep2)) in
+      // the definition of _c2.  The latter is more accurate for very oblate
+      // ellipsoids (which the Geodesic class does not attempt to handle).  Of
+      // course, the area calculation in GeodesicExact is still based on a
+      // series and so only holds for moderately oblate (or prolate)
+      // ellipsoids.
     , _c2((Math::sq(_a) + Math::sq(_b) *
-           (_e2 == 0 ? 1 :
-            (_e2 > 0 ? Math::atanh(sqrt(_e2)) : atan(sqrt(-_e2))) /
+           (_f == 0 ? 1 :
+            (_f > 0 ? Math::asinh(sqrt(_ep2)) : atan(sqrt(-_e2))) /
             sqrt(abs(_e2))))/2) // authalic radius squared
       // The sig12 threshold for "really short".  Using the auxiliary sphere
       // solution with dnm computed at (bet1 + bet2) / 2, the relative error in
@@ -144,13 +150,13 @@ namespace GeographicLib {
     real lon12 = Math::AngDiff(Math::AngNormalize(lon1),
                                Math::AngNormalize(lon2));
     // If very close to being on the same half-meridian, then make it so.
-    lon12 = AngRound(lon12);
+    lon12 = Math::AngRound(lon12);
     // Make longitude difference positive.
     int lonsign = lon12 >= 0 ? 1 : -1;
     lon12 *= lonsign;
     // If really close to the equator, treat as on equator.
-    lat1 = AngRound(lat1);
-    lat2 = AngRound(lat2);
+    lat1 = Math::AngRound(lat1);
+    lat2 = Math::AngRound(lat2);
     // Swap points so that point with higher (abs) latitude is point 1
     int swapp = abs(lat1) >= abs(lat2) ? 1 : -1;
     if (swapp < 0) {
@@ -182,13 +188,13 @@ namespace GeographicLib {
     // Ensure cbet1 = +epsilon at poles
     sbet1 = _f1 * sin(phi);
     cbet1 = lat1 == -90 ? tiny_ : cos(phi);
-    SinCosNorm(sbet1, cbet1);
+    Math::norm(sbet1, cbet1);
 
     phi = lat2 * Math::degree();
     // Ensure cbet2 = +epsilon at poles
     sbet2 = _f1 * sin(phi);
     cbet2 = abs(lat2) == 90 ? tiny_ : cos(phi);
-    SinCosNorm(sbet2, cbet2);
+    Math::norm(sbet2, cbet2);
 
     // If cbet1 < -sbet1, then cbet2 - cbet1 is a sensitive measure of the
     // |bet1| - |bet2|.  Alternatively (cbet1 >= -sbet1), abs(sbet2) + sbet1 is
@@ -358,7 +364,7 @@ namespace GeographicLib {
             if (nsalp1 > 0 && abs(dalp1) < Math::pi()) {
               calp1 = calp1 * cdalp1 - salp1 * sdalp1;
               salp1 = nsalp1;
-              SinCosNorm(salp1, calp1);
+              Math::norm(salp1, calp1);
               // In some regimes we don't get quadratic convergence because
               // slope -> 0.  So use convergence conditions based on epsilon
               // instead of sqrt(epsilon).
@@ -376,7 +382,7 @@ namespace GeographicLib {
           // WGS84 and random input: mean = 4.74, sd = 0.99
           salp1 = (salp1a + salp1b)/2;
           calp1 = (calp1a + calp1b)/2;
-          SinCosNorm(salp1, calp1);
+          Math::norm(salp1, calp1);
           tripn = false;
           tripb = (abs(salp1a - salp1) + (calp1a - calp1) < tolb_ ||
                    abs(salp1 - salp1b) + (calp1 - calp1b) < tolb_);
@@ -414,8 +420,8 @@ namespace GeographicLib {
           eps = k2 / (2 * (1 + sqrt(1 + k2)) + k2),
           // Multiplier = a^2 * e^2 * cos(alpha0) * sin(alpha0).
           A4 = Math::sq(_a) * calp0 * salp0 * _e2;
-        SinCosNorm(ssig1, csig1);
-        SinCosNorm(ssig2, csig2);
+        Math::norm(ssig1, csig1);
+        Math::norm(ssig2, csig2);
         real C4a[nC4_];
         C4f(eps, C4a);
         real
@@ -471,8 +477,8 @@ namespace GeographicLib {
 
     if (outmask & AZIMUTH) {
       // minus signs give range [-180, 180). 0- converts -0 to +0.
-      azi1 = 0 - atan2(-salp1, calp1) / Math::degree();
-      azi2 = 0 - atan2(-salp2, calp2) / Math::degree();
+      azi1 = Math::atan2d(salp1, calp1);
+      azi2 = Math::atan2d(salp2, calp2);
     }
 
     // Returned value in [0, 180]
@@ -623,7 +629,7 @@ namespace GeographicLib {
       salp2 = cbet1 * somg12;
       calp2 = sbet12 - cbet1 * sbet2 *
         (comg12 >= 0 ? Math::sq(somg12) / (1 + comg12) : 1 - comg12);
-      SinCosNorm(salp2, calp2);
+      Math::norm(salp2, calp2);
       // Set return value
       sig12 = atan2(ssig12, csig12);
     } else if (abs(_n) > real(0.1) || // Skip astroid calc if too eccentric
@@ -723,7 +729,7 @@ namespace GeographicLib {
     }
     // Sanity check on starting guess.  Backwards check allows NaN through.
     if (!(salp1 <= 0))
-      SinCosNorm(salp1, calp1);
+      Math::norm(salp1, calp1);
     else {
       salp1 = 1; calp1 = 0;
     }
@@ -759,9 +765,9 @@ namespace GeographicLib {
     csig1 = comg1 = calp1 * cbet1;
     // Without normalization we have schi1 = somg1.
     cchi1 = _f1 * dn1 * comg1;
-    SinCosNorm(ssig1, csig1);
-    // SinCosNorm(somg1, comg1); -- don't need to normalize!
-    // SinCosNorm(schi1, cchi1); -- don't need to normalize!
+    Math::norm(ssig1, csig1);
+    // Math::norm(somg1, comg1); -- don't need to normalize!
+    // Math::norm(schi1, cchi1); -- don't need to normalize!
 
     // Enforce symmetries in the case abs(bet2) = -bet1.  Need to be careful
     // about this case, since this can yield singularities in the Newton
@@ -784,9 +790,9 @@ namespace GeographicLib {
     csig2 = comg2 = calp2 * cbet2;
     // Without normalization we have schi2 = somg2.
     cchi2 = _f1 * dn2 * comg2;
-    SinCosNorm(ssig2, csig2);
-    // SinCosNorm(somg2, comg2); -- don't need to normalize!
-    // SinCosNorm(schi2, cchi2); -- don't need to normalize!
+    Math::norm(ssig2, csig2);
+    // Math::norm(somg2, comg2); -- don't need to normalize!
+    // Math::norm(schi2, cchi2); -- don't need to normalize!
 
     // sig12 = sig2 - sig1, limit to [0, pi]
     sig12 = atan2(max(csig1 * ssig2 - ssig1 * csig2, real(0)),
diff --git a/src/GeodesicLine.cpp b/src/GeodesicLine.cpp
index b9be956..39b1af7 100644
--- a/src/GeodesicLine.cpp
+++ b/src/GeodesicLine.cpp
@@ -2,7 +2,7 @@
  * \file GeodesicLine.cpp
  * \brief Implementation for GeographicLib::GeodesicLine class
  *
- * Copyright (c) Charles Karney (2009-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2009-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  *
@@ -39,7 +39,7 @@ namespace GeographicLib {
     , _lat1(lat1)
     , _lon1(lon1)
     // Guard against underflow in salp0
-    , _azi1(Geodesic::AngRound(Math::AngNormalize(azi1)))
+    , _azi1(Math::AngRound(Math::AngNormalize(azi1)))
     , _a(g._a)
     , _f(g._f)
     , _b(g._b)
@@ -58,7 +58,7 @@ namespace GeographicLib {
     // Ensure cbet1 = +epsilon at poles
     sbet1 = _f1 * sin(phi);
     cbet1 = abs(lat1) == 90 ? tiny_ : cos(phi);
-    Geodesic::SinCosNorm(sbet1, cbet1);
+    Math::norm(sbet1, cbet1);
     _dn1 = sqrt(1 + g._ep2 * Math::sq(sbet1));
 
     // Evaluate alp0 from sin(alp1) * cos(bet1) = sin(alp0),
@@ -77,8 +77,8 @@ namespace GeographicLib {
     // With alp0 = 0, omg1 = 0 for alp1 = 0, omg1 = pi for alp1 = pi.
     _ssig1 = sbet1; _somg1 = _salp0 * sbet1;
     _csig1 = _comg1 = sbet1 != 0 || _calp1 != 0 ? cbet1 * _calp1 : 1;
-    Geodesic::SinCosNorm(_ssig1, _csig1); // sig1 in (-pi, pi]
-    // Geodesic::SinCosNorm(_somg1, _comg1); -- don't need to normalize!
+    Math::norm(_ssig1, _csig1); // sig1 in (-pi, pi]
+    // Math::norm(_somg1, _comg1); -- don't need to normalize!
 
     _k2 = Math::sq(_calp0) * g._ep2;
     real eps = _k2 / (2 * (1 + sqrt(1 + _k2)) + _k2);
@@ -233,7 +233,7 @@ namespace GeographicLib {
 
     if (outmask & AZIMUTH)
       // minus signs give range [-180, 180). 0- converts -0 to +0.
-      azi2 = 0 - atan2(-salp2, calp2) / Math::degree();
+      azi2 = Math::atan2d(salp2, calp2);
 
     if (outmask & (REDUCEDLENGTH | GEODESICSCALE)) {
       real
diff --git a/src/GeodesicLineExact.cpp b/src/GeodesicLineExact.cpp
index 02d6c9c..e282377 100644
--- a/src/GeodesicLineExact.cpp
+++ b/src/GeodesicLineExact.cpp
@@ -2,7 +2,7 @@
  * \file GeodesicLineExact.cpp
  * \brief Implementation for GeographicLib::GeodesicLineExact class
  *
- * Copyright (c) Charles Karney (2012-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2012-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  *
@@ -39,7 +39,7 @@ namespace GeographicLib {
     , _lat1(lat1)
     , _lon1(lon1)
     // Guard against underflow in salp0
-    , _azi1(GeodesicExact::AngRound(Math::AngNormalize(azi1)))
+    , _azi1(Math::AngRound(Math::AngNormalize(azi1)))
     , _a(g._a)
     , _f(g._f)
     , _b(g._b)
@@ -60,7 +60,7 @@ namespace GeographicLib {
     // Ensure cbet1 = +epsilon at poles
     sbet1 = _f1 * sin(phi);
     cbet1 = abs(lat1) == 90 ? tiny_ : cos(phi);
-    GeodesicExact::SinCosNorm(sbet1, cbet1);
+    Math::norm(sbet1, cbet1);
     _dn1 = (_f >= 0 ? sqrt(1 + g._ep2 * Math::sq(sbet1)) :
             sqrt(1 - _e2 * Math::sq(cbet1)) / _f1);
 
@@ -82,9 +82,9 @@ namespace GeographicLib {
     _csig1 = _comg1 = sbet1 != 0 || _calp1 != 0 ? cbet1 * _calp1 : 1;
     // Without normalization we have schi1 = somg1.
     _cchi1 = _f1 * _dn1 * _comg1;
-    GeodesicExact::SinCosNorm(_ssig1, _csig1); // sig1 in (-pi, pi]
-    // GeodesicExact::SinCosNorm(_somg1, _comg1); -- don't need to normalize!
-    // GeodesicExact::SinCosNorm(_schi1, _cchi1); -- don't need to normalize!
+    Math::norm(_ssig1, _csig1); // sig1 in (-pi, pi]
+    // Math::norm(_somg1, _comg1); -- don't need to normalize!
+    // Math::norm(_schi1, _cchi1); -- don't need to normalize!
 
     _k2 = Math::sq(_calp0) * g._ep2;
     _E.Reset(-_k2, -g._ep2, 1 + _k2, 1 + g._ep2);
@@ -201,7 +201,7 @@ namespace GeographicLib {
 
     if (outmask & AZIMUTH)
       // minus signs give range [-180, 180). 0- converts -0 to +0.
-      azi2 = 0 - atan2(-salp2, calp2) / Math::degree();
+      azi2 = Math::atan2d(salp2, calp2);
 
     if (outmask & (REDUCEDLENGTH | GEODESICSCALE)) {
       real J12 = _k2 * _D0 * (sig12 + _E.deltaD(ssig2, csig2, dn2) - _D1);
diff --git a/src/GeographicLib.pro b/src/GeographicLib.pro
index 387f24e..5f72f7b 100644
--- a/src/GeographicLib.pro
+++ b/src/GeographicLib.pro
@@ -1,4 +1,4 @@
-VERSION = 14.0.2
+VERSION = 14.0.3
 
 TEMPLATE = lib
 
@@ -30,6 +30,7 @@ SOURCES += LocalCartesian.cpp
 SOURCES += MGRS.cpp
 SOURCES += MagneticCircle.cpp
 SOURCES += MagneticModel.cpp
+SOURCES += Math.cpp
 SOURCES += NormalGravity.cpp
 SOURCES += OSGB.cpp
 SOURCES += PolarStereographic.cpp
diff --git a/src/Geoid.cpp b/src/Geoid.cpp
index a7c8564..0ebe3ca 100644
--- a/src/Geoid.cpp
+++ b/src/Geoid.cpp
@@ -8,6 +8,7 @@
  **********************************************************************/
 
 #include <GeographicLib/Geoid.hpp>
+// For getenv
 #include <cstdlib>
 #include <GeographicLib/Utility.hpp>
 
diff --git a/src/LambertConformalConic.cpp b/src/LambertConformalConic.cpp
index d5c4613..98fbe53 100644
--- a/src/LambertConformalConic.cpp
+++ b/src/LambertConformalConic.cpp
@@ -2,18 +2,13 @@
  * \file LambertConformalConic.cpp
  * \brief Implementation for GeographicLib::LambertConformalConic class
  *
- * Copyright (c) Charles Karney (2010-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2010-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  **********************************************************************/
 
 #include <GeographicLib/LambertConformalConic.hpp>
 
-#if defined(_MSC_VER)
-// Squelch warnings about constant conditional expressions
-#  pragma warning (disable: 4127)
-#endif
-
 namespace GeographicLib {
 
   using namespace std;
@@ -22,14 +17,12 @@ namespace GeographicLib {
                                                real stdlat, real k0)
     : eps_(numeric_limits<real>::epsilon())
     , epsx_(Math::sq(eps_))
-    , tol_(real(0.1) * sqrt(eps_))
     , ahypover_(Math::digits() * log(real(numeric_limits<real>::radix)) + 2)
     , _a(a)
     , _f(f <= 1 ? f : 1/f)
     , _fm(1 - _f)
     , _e2(_f * (2 - _f))
-    , _e(sqrt(abs(_e2)))
-    , _e2m(1 - _e2)
+    , _es((_f < 0 ? -1 : 1) * sqrt(abs(_e2)))
   {
     if (!(Math::isfinite(_a) && _a > 0))
       throw GeographicErr("Major radius is not positive");
@@ -51,14 +44,12 @@ namespace GeographicLib {
                                                real k1)
     : eps_(numeric_limits<real>::epsilon())
     , epsx_(Math::sq(eps_))
-    , tol_(real(0.1) * sqrt(eps_))
     , ahypover_(Math::digits() * log(real(numeric_limits<real>::radix)) + 2)
     , _a(a)
     , _f(f <= 1 ? f : 1/f)
     , _fm(1 - _f)
     , _e2(_f * (2 - _f))
-    , _e(sqrt(abs(_e2)))
-    , _e2m(1 - _e2)
+    , _es((_f < 0 ? -1 : 1) * sqrt(abs(_e2)))
   {
     if (!(Math::isfinite(_a) && _a > 0))
       throw GeographicErr("Major radius is not positive");
@@ -83,14 +74,12 @@ namespace GeographicLib {
                                                real k1)
     : eps_(numeric_limits<real>::epsilon())
     , epsx_(Math::sq(eps_))
-    , tol_(real(0.1) * sqrt(eps_))
     , ahypover_(Math::digits() * log(real(numeric_limits<real>::radix)) + 2)
     , _a(a)
     , _f(f <= 1 ? f : 1/f)
     , _fm(1 - _f)
     , _e2(_f * (2 - _f))
-    , _e(sqrt(abs(_e2)))
-    , _e2m(1 - _e2)
+    , _es((_f < 0 ? -1 : 1) * sqrt(abs(_e2)))
   {
     if (!(Math::isfinite(_a) && _a > 0))
       throw GeographicErr("Major radius is not positive");
@@ -157,10 +146,10 @@ namespace GeographicLib {
       tbet2 = _fm * tphi2, scbet2 = hyp(tbet2);
     real
       scphi1 = 1/cphi1,
-      xi1 = eatanhe(sphi1), shxi1 = sinh(xi1), chxi1 = hyp(shxi1),
+      xi1 = Math::eatanhe(sphi1, _es), shxi1 = sinh(xi1), chxi1 = hyp(shxi1),
       tchi1 = chxi1 * tphi1 - shxi1 * scphi1, scchi1 = hyp(tchi1),
       scphi2 = 1/cphi2,
-      xi2 = eatanhe(sphi2), shxi2 = sinh(xi2), chxi2 = hyp(shxi2),
+      xi2 = Math::eatanhe(sphi2, _es), shxi2 = sinh(xi2), chxi2 = hyp(shxi2),
       tchi2 = chxi2 * tphi2 - shxi2 * scphi2, scchi2 = hyp(tchi2),
       psi1 = Math::asinh(tchi1);
     if (tphi2 - tphi1 != 0) {
@@ -248,7 +237,8 @@ namespace GeographicLib {
         // dchi = ((mu2 + mu1) - D(nu2, nu1) * (scphi2 + scphi1)) /
         //         D(tchi2, tchi1)
         real
-          xiZ = eatanhe(real(1)), shxiZ = sinh(xiZ), chxiZ = hyp(shxiZ),
+          xiZ = Math::eatanhe(real(1), _es),
+          shxiZ = sinh(xiZ), chxiZ = hyp(shxiZ),
           // These are differences not divided differences
           // dxiZ1 = xiZ - xi1; dshxiZ1 = shxiZ - shxi; dchxiZ1 = chxiZ - chxi
           dxiZ1 = Deatanhe(real(1), sphi1)/(scphi1*(tphi1+scphi1)),
@@ -295,7 +285,7 @@ namespace GeographicLib {
     }
 
     _scbet0 = hyp(_fm * tphi0);
-    real shxi0 = sinh(eatanhe(_n));
+    real shxi0 = sinh(Math::eatanhe(_n, _es));
     _tchi0 = tphi0 * hyp(shxi0) - shxi0 * hyp(tphi0); _scchi0 = hyp(_tchi0);
     _psi0 = Math::asinh(_tchi0);
 
@@ -322,7 +312,7 @@ namespace GeographicLib {
       real
         sphi = -1, cphi =  epsx_,
         tphi = sphi/cphi,
-        scphi = 1/cphi, shxi = sinh(eatanhe(sphi)),
+        scphi = 1/cphi, shxi = sinh(Math::eatanhe(sphi, _es)),
         tchi = hyp(shxi) * tphi - shxi * scphi, scchi = hyp(tchi),
         psi = Math::asinh(tchi),
         dpsi = Dasinh(tchi, _tchi0, scchi, _scchi0) * (tchi - _tchi0);
@@ -360,7 +350,7 @@ namespace GeographicLib {
       phi = _sign * lat * Math::degree(),
       sphi = sin(phi), cphi = abs(lat) != 90 ? cos(phi) : epsx_,
       tphi = sphi/cphi, scbet = hyp(_fm * tphi),
-      scphi = 1/cphi, shxi = sinh(eatanhe(sphi)),
+      scphi = 1/cphi, shxi = sinh(Math::eatanhe(sphi, _es)),
       tchi = hyp(shxi) * tphi - shxi * scphi, scchi = hyp(tchi),
       psi = Math::asinh(tchi),
       theta = _n * lam, stheta = sin(theta), ctheta = cos(theta),
@@ -436,26 +426,10 @@ namespace GeographicLib {
       tchi = sh * (tn + 1/tn)/2 - hyp(sh) * (tnm1 * (tn + 1)/tn)/2;
     }
 
-    // Use Newton's method to solve for tphi
-    real
-      // See comment in TransverseMercator.cpp about the initial guess
-      tphi = tchi/_e2m,
-      stol = tol_ * max(real(1), abs(tchi));
-    // min iterations = 1, max iterations = 2; mean = 1.94
-    for (int i = 0; i < numit_ || GEOGRAPHICLIB_PANIC; ++i) {
-      real
-        scphi = hyp(tphi),
-        shxi = sinh( eatanhe( tphi / scphi ) ),
-        tchia = hyp(shxi) * tphi - shxi * scphi,
-        dtphi = (tchi - tchia) * (1 + _e2m * Math::sq(tphi)) /
-        ( _e2m * scphi * hyp(tchia) );
-      tphi += dtphi;
-      if (!(abs(dtphi) >= stol))
-        break;
-    }
     // log(t) = -asinh(tan(chi)) = -psi
     gamma = atan2(nx, y1);
     real
+      tphi = Math::tauf(tchi, _es),
       phi = _sign * atan(tphi),
       scbet = hyp(_fm * tphi), scchi = hyp(tchi),
       lam = _n ? gamma / _n : x / y1;
diff --git a/src/LocalCartesian.cpp b/src/LocalCartesian.cpp
index ba243eb..6749172 100644
--- a/src/LocalCartesian.cpp
+++ b/src/LocalCartesian.cpp
@@ -25,10 +25,11 @@ namespace GeographicLib {
       lam = lon0 * Math::degree(),
       slam = _lon0 == -180 ? 0 : sin(lam),
       clam = abs(_lon0) == 90 ? 0 : cos(lam);
-    _earth.Rotation(sphi, cphi, slam, clam, _r);
+    Geocentric::Rotation(sphi, cphi, slam, clam, _r);
   }
 
   void LocalCartesian::MatrixMultiply(real M[dim2_]) const {
+    // M = r' . M
     real t[dim2_];
     copy(M, M + dim2_, t);
     for (size_t i = 0; i < dim2_; ++i) {
diff --git a/src/MagneticModel.cpp b/src/MagneticModel.cpp
index 3be2255..8eb65f6 100644
--- a/src/MagneticModel.cpp
+++ b/src/MagneticModel.cpp
@@ -2,8 +2,8 @@
  * \file MagneticModel.cpp
  * \brief Implementation for GeographicLib::MagneticModel class
  *
- * Copyright (c) Charles Karney (2011) <charles at karney.com> and licensed under
- * the MIT/X11 License.  For more information, see
+ * Copyright (c) Charles Karney (2011-2015) <charles at karney.com> and licensed
+ * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  **********************************************************************/
 
@@ -221,11 +221,11 @@ namespace GeographicLib {
                                       real& Dt, real& It) {
     H = Math::hypot(Bx, By);
     Ht = H ? (Bx * Bxt + By * Byt) / H : Math::hypot(Bxt, Byt);
-    D = (0 - (H ? atan2(-Bx, By) : atan2(-Bxt, Byt))) / Math::degree();
+    D = H ? Math::atan2d(Bx, By) : Math::atan2d(Bxt, Byt);
     Dt = (H ? (By * Bxt - Bx * Byt) / Math::sq(H) : 0) / Math::degree();
     F = Math::hypot(H, Bz);
     Ft = F ? (H * Ht + Bz * Bzt) / F : Math::hypot(Ht, Bzt);
-    I = (F ? atan2(-Bz, H) : atan2(-Bzt, Ht)) / Math::degree();
+    I = F ? Math::atan2d(-Bz, H) : Math::atan2d(-Bzt, Ht);
     It = (F ? (Bz * Ht - H * Bzt) / Math::sq(F) : 0) / Math::degree();
   }
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 3ed6a3c..911acc8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -34,6 +34,7 @@ libGeographic_la_SOURCES = Accumulator.cpp \
 		MGRS.cpp \
 		MagneticCircle.cpp \
 		MagneticModel.cpp \
+		Math.cpp \
 		NormalGravity.cpp \
 		OSGB.cpp \
 		PolarStereographic.cpp \
diff --git a/src/Makefile.in b/src/Makefile.in
index 8ebbf75..c17b475 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994-2013 Free Software Foundation, Inc.
@@ -135,8 +135,8 @@ am_libGeographic_la_OBJECTS = Accumulator.lo AlbersEqualArea.lo \
 	GeodesicLine.lo GeodesicLineExact.lo Geohash.lo Geoid.lo \
 	Gnomonic.lo GravityCircle.lo GravityModel.lo \
 	LambertConformalConic.lo LocalCartesian.lo MGRS.lo \
-	MagneticCircle.lo MagneticModel.lo NormalGravity.lo OSGB.lo \
-	PolarStereographic.lo PolygonArea.lo Rhumb.lo \
+	MagneticCircle.lo MagneticModel.lo Math.lo NormalGravity.lo \
+	OSGB.lo PolarStereographic.lo PolygonArea.lo Rhumb.lo \
 	SphericalEngine.lo TransverseMercator.lo \
 	TransverseMercatorExact.lo UTMUPS.lo Utility.lo
 libGeographic_la_OBJECTS = $(am_libGeographic_la_OBJECTS)
@@ -391,6 +391,7 @@ libGeographic_la_SOURCES = Accumulator.cpp \
 		MGRS.cpp \
 		MagneticCircle.cpp \
 		MagneticModel.cpp \
+		Math.cpp \
 		NormalGravity.cpp \
 		OSGB.cpp \
 		PolarStereographic.cpp \
@@ -548,6 +549,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/MGRS.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/MagneticCircle.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/MagneticModel.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Math.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/NormalGravity.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/OSGB.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/PolarStereographic.Plo at am__quote@
diff --git a/src/Makefile.mk b/src/Makefile.mk
index 6da6f6f..c970889 100644
--- a/src/Makefile.mk
+++ b/src/Makefile.mk
@@ -32,6 +32,7 @@ MODULES = Accumulator \
 	MGRS \
 	MagneticCircle \
 	MagneticModel \
+	Math \
 	NormalGravity \
 	OSGB \
 	PolarStereographic \
@@ -43,7 +44,6 @@ MODULES = Accumulator \
 	UTMUPS \
 	Utility
 EXTRAHEADERS = Constants \
-	Math \
 	SphericalHarmonic \
 	SphericalHarmonic1 \
 	SphericalHarmonic2
@@ -119,6 +119,7 @@ MagneticCircle.o: CircularEngine.hpp Config.h Constants.hpp Geocentric.hpp \
 MagneticModel.o: CircularEngine.hpp Config.h Constants.hpp Geocentric.hpp \
 	MagneticCircle.hpp MagneticModel.hpp Math.hpp SphericalEngine.hpp \
 	SphericalHarmonic.hpp Utility.hpp
+Math.o: Config.h Constants.hpp Math.hpp
 NormalGravity.o: Config.h Constants.hpp Geocentric.hpp Math.hpp \
 	NormalGravity.hpp
 OSGB.o: Config.h Constants.hpp Math.hpp OSGB.hpp TransverseMercator.hpp \
diff --git a/src/Math.cpp b/src/Math.cpp
new file mode 100644
index 0000000..cad928a
--- /dev/null
+++ b/src/Math.cpp
@@ -0,0 +1,65 @@
+/**
+ * \file Math.cpp
+ * \brief Implementation for GeographicLib::Math class
+ *
+ * Copyright (c) Charles Karney (2015) <charles at karney.com> and licensed
+ * under the MIT/X11 License.  For more information, see
+ * http://geographiclib.sourceforge.net/
+ **********************************************************************/
+
+#include <GeographicLib/Math.hpp>
+
+#if defined(_MSC_VER)
+// Squelch warnings about constant conditional expressions
+#  pragma warning (disable: 4127)
+#endif
+
+namespace GeographicLib {
+
+  /// \cond SKIP
+
+  using namespace std;
+
+  template<typename T> T Math::eatanhe(T x, T es)  {
+    return es > T(0) ? es * atanh(es * x) : -es * atan(es * x);
+  }
+
+  template<typename T> T Math::taupf(T tau, T es) {
+    T tau1 = hypot(T(1), tau),
+      sig = sinh( eatanhe(tau / tau1, es ) );
+    return hypot(T(1), sig) * tau - sig * tau1;
+  }
+
+  template<typename T> T Math::tauf(T taup, T es) {
+    static const int numit = 5;
+    static const T tol = sqrt(numeric_limits<T>::epsilon()) / T(10);
+    T e2m = T(1) - sq(es),
+      // To lowest order in e^2, taup = (1 - e^2) * tau = _e2m * tau; so use
+      // tau = taup/_e2m as a starting guess.  (This starting guess is the
+      // geocentric latitude which, to first order in the flattening, is equal
+      // to the conformal latitude.)  Only 1 iteration is needed for |lat| <
+      // 3.35 deg, otherwise 2 iterations are needed.  If, instead, tau = taup
+      // is used the mean number of iterations increases to 1.99 (2 iterations
+      // are needed except near tau = 0).
+      tau = taup/e2m,
+      stol = tol * max(T(1), abs(taup));
+    // min iterations = 1, max iterations = 2; mean = 1.94
+    for (int i = 0; i < numit || GEOGRAPHICLIB_PANIC; ++i) {
+      T taupa = taupf(tau, es),
+        dtau = (taup - taupa) * (1 + e2m * sq(tau)) /
+        ( e2m * hypot(T(1), tau) * hypot(T(1), taupa) );
+      tau += dtau;
+      if (!(abs(dtau) >= stol))
+        break;
+    }
+    return tau;
+  }
+
+  // Instantiate
+  template Math::real Math::eatanhe<Math::real>(Math::real, Math::real);
+  template Math::real Math::taupf<Math::real>(Math::real, Math::real);
+  template Math::real Math::tauf<Math::real>(Math::real, Math::real);
+
+  /// \endcond
+
+} // namespace GeographicLib
diff --git a/src/PolarStereographic.cpp b/src/PolarStereographic.cpp
index ce4409c..3ed4b1e 100644
--- a/src/PolarStereographic.cpp
+++ b/src/PolarStereographic.cpp
@@ -2,31 +2,24 @@
  * \file PolarStereographic.cpp
  * \brief Implementation for GeographicLib::PolarStereographic class
  *
- * Copyright (c) Charles Karney (2008-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2008-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  **********************************************************************/
 
 #include <GeographicLib/PolarStereographic.hpp>
 
-#if defined(_MSC_VER)
-// Squelch warnings about constant conditional expressions
-#  pragma warning (disable: 4127)
-#endif
-
 namespace GeographicLib {
 
   using namespace std;
 
   PolarStereographic::PolarStereographic(real a, real f, real k0)
-    : tol_(real(0.1)*sqrt(numeric_limits<real>::epsilon()))
-    , _a(a)
+    : _a(a)
     , _f(f <= 1 ? f : 1/f)
     , _e2(_f * (2 - _f))
-    , _e(sqrt(abs(_e2)))
+    , _es((_f < 0 ? -1 : 0) * sqrt(abs(_e2)))
     , _e2m(1 - _e2)
-    , _Cx(exp(eatanhe(real(1))))
-    , _c( (1 - _f) * _Cx )
+    , _c( (1 - _f) * exp(Math::eatanhe(real(1), _es)) )
     , _k0(k0)
   {
     if (!(Math::isfinite(_a) && _a > 0))
@@ -70,11 +63,9 @@ namespace GeographicLib {
     const {
     lat *= northp ? 1 : -1;
     real
-      phi = lat * Math::degree(),
-      tau = lat != -90 ? tanx(phi) : -overflow(),
+      tau = Math::tand(lat),
       secphi = Math::hypot(real(1), tau),
-      sig = sinh( eatanhe(tau / secphi) ),
-      taup = Math::hypot(real(1), sig) * tau - sig * secphi,
+      taup = Math::taupf(tau, _es),
       rho = Math::hypot(real(1), taup) + abs(taup);
     rho = taup >= 0 ? (lat != 90 ? 1/rho : 0) : rho;
     rho *= 2 * _k0 * _a / _c;
@@ -95,28 +86,12 @@ namespace GeographicLib {
       rho = Math::hypot(x, y),
       t = rho / (2 * _k0 * _a / _c),
       taup = (1 / t - t) / 2,
-      tau = taup * _Cx,
-      stol = tol_ * max(real(1), abs(taup));
-    if (abs(tau) < overflow()) {
-      // min iterations = 1, max iterations = 2; mean = 1.99
-      for (int i = 0; i < numit_ || GEOGRAPHICLIB_PANIC; ++i) {
-        real
-          tau1 = Math::hypot(real(1), tau),
-          sig = sinh( eatanhe( tau / tau1 ) ),
-          taupa = Math::hypot(real(1), sig) * tau - sig * tau1,
-          dtau = (taup - taupa) * (1 + _e2m * Math::sq(tau)) /
-          ( _e2m * tau1 * Math::hypot(real(1), taupa) );
-        tau += dtau;
-        if (!(abs(dtau) >= stol))
-          break;
-      }
-    }
-    real
+      tau = Math::tauf(taup, _es),
       phi = atan(tau),
       secphi = Math::hypot(real(1), tau);
     k = rho ? (rho / _a) * secphi * sqrt(_e2m + _e2 / Math::sq(secphi)) : _k0;
     lat = (northp ? 1 : -1) * (rho ? phi / Math::degree() : 90);
-    lon = -atan2( -x, northp ? -y : y ) / Math::degree();
+    lon = 0 - atan2( -x, northp ? -y : y ) / Math::degree();
     gamma = northp ? lon : -lon;
   }
 
diff --git a/src/Rhumb.cpp b/src/Rhumb.cpp
index 8b9d677..17d4cdf 100644
--- a/src/Rhumb.cpp
+++ b/src/Rhumb.cpp
@@ -3,8 +3,8 @@
  * \brief Implementation for GeographicLib::Rhumb and GeographicLib::RhumbLine
  * classes
  *
- * Copyright (c) Charles Karney (2014) <charles at karney.com> and licensed under
- * the MIT/X11 License.  For more information, see
+ * Copyright (c) Charles Karney (2014-2015) <charles at karney.com> and licensed
+ * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  **********************************************************************/
 
@@ -121,14 +121,14 @@ namespace GeographicLib {
       psi12 = psi2 - psi1,
       h = Math::hypot(lon12, psi12);
     if (outmask & AZIMUTH)
-      azi12 = 0 - atan2(-lon12, psi12) / Math::degree();
-    psi1 *= Math::degree();
-    psi2 *= Math::degree();
-    real dmudpsi = DIsometricToRectifying(psi2, psi1);
-    if (outmask & DISTANCE)
+      azi12 = Math::atan2d(lon12, psi12);
+    if (outmask & DISTANCE) {
+      real dmudpsi = DIsometricToRectifying(psi2, psi1);
       s12 = h * dmudpsi * _ell.QuarterMeridian() / 90;
+    }
     if (outmask & AREA)
-      S12 = _c2 * lon12 * MeanSinXi(psi2, psi1);
+      S12 = _c2 * lon12 *
+        MeanSinXi(psi2 * Math::degree(), psi1 * Math::degree());
   }
 
   RhumbLine Rhumb::Line(real lat1, real lon1, real azi12) const
@@ -170,17 +170,17 @@ namespace GeographicLib {
 
   Math::real Rhumb::DRectifying(real latx, real laty) const {
     real
-      phix = latx * Math::degree(), tbetx = _ell._f1 * tano(phix),
-      phiy = laty * Math::degree(), tbety = _ell._f1 * tano(phiy);
+      tbetx = _ell._f1 * Math::tand(latx),
+      tbety = _ell._f1 * Math::tand(laty);
     return (Math::pi()/2) * _ell._b * _ell._f1 * DE(atan(tbetx), atan(tbety))
-      * Dtan(phix, phiy) * Datan(tbetx, tbety) / _ell.QuarterMeridian();
+      * Dtan(latx, laty) * Datan(tbetx, tbety) / _ell.QuarterMeridian();
   }
 
   Math::real Rhumb::DIsometric(real latx, real laty) const {
     real
-      phix = latx * Math::degree(), tx = tano(phix),
-      phiy = laty * Math::degree(), ty = tano(phiy);
-    return Dasinh(tx, ty) * Dtan(phix, phiy)
+      phix = latx * Math::degree(), tx = Math::tand(latx),
+      phiy = laty * Math::degree(), ty = Math::tand(laty);
+    return Dasinh(tx, ty) * Dtan(latx, laty)
       - Deatanhe(sin(phix), sin(phiy)) * Dsin(phix, phiy);
   }
 
@@ -268,11 +268,14 @@ namespace GeographicLib {
   Math::real Rhumb::DIsometricToRectifying(real psix, real psiy) const {
     if (_exact) {
       real
-        latx = _ell.InverseIsometricLatitude(psix/Math::degree()),
-        laty = _ell.InverseIsometricLatitude(psiy/Math::degree());
+        latx = _ell.InverseIsometricLatitude(psix),
+        laty = _ell.InverseIsometricLatitude(psiy);
       return DRectifying(latx, laty) / DIsometric(latx, laty);
-    } else
+    } else {
+      psix *= Math::degree();
+      psiy *= Math::degree();
       return DConformalToRectifying(gd(psix), gd(psiy)) * Dgd(psix, psiy);
+    }
   }
 
   Math::real Rhumb::DRectifyingToIsometric(real mux, real muy) const {
@@ -281,8 +284,8 @@ namespace GeographicLib {
       laty = _ell.InverseRectifyingLatitude(muy/Math::degree());
     return _exact ?
       DIsometric(latx, laty) / DRectifying(latx, laty) :
-      Dgdinv(_ell.ConformalLatitude(latx) * Math::degree(),
-             _ell.ConformalLatitude(laty) * Math::degree()) *
+      Dgdinv(Math::taupf(Math::tand(latx), _ell._es),
+             Math::taupf(Math::tand(laty), _ell._es)) *
       DRectifyingToConformal(mux, muy);
   }
 
diff --git a/src/TransverseMercator.cpp b/src/TransverseMercator.cpp
index 2d035c6..04d0cb7 100644
--- a/src/TransverseMercator.cpp
+++ b/src/TransverseMercator.cpp
@@ -41,26 +41,20 @@
 
 #include <GeographicLib/TransverseMercator.hpp>
 
-#if defined(_MSC_VER)
-// Squelch warnings about constant conditional expressions
-#  pragma warning (disable: 4127)
-#endif
-
 namespace GeographicLib {
 
   using namespace std;
 
   TransverseMercator::TransverseMercator(real a, real f, real k0)
-    : tol_(real(0.1)*sqrt(numeric_limits<real>::epsilon()))
-    , _a(a)
+    : _a(a)
     , _f(f <= 1 ? f : 1/f)
     , _k0(k0)
     , _e2(_f * (2 - _f))
-    , _e(sqrt(abs(_e2)))
+    , _es((f < 0 ? -1 : 1) * sqrt(abs(_e2)))
     , _e2m(1 - _e2)
       // _c = sqrt( pow(1 + _e, 1 + _e) * pow(1 - _e, 1 - _e) ) )
       // See, for example, Lee (1976), p 100.
-    , _c( sqrt(_e2m) * exp(eatanhe(real(1))) )
+    , _c( sqrt(_e2m) * exp(Math::eatanhe(real(1), _es)) )
     , _n(_f / (2 - _f))
   {
     if (!(Math::isfinite(_a) && _a > 0))
@@ -271,55 +265,11 @@ namespace GeographicLib {
   //     S = sum(c[i]*sin(2*i*phi),i,1,6)
   //     taup = (tau + tan(S)) / (1 - tau * tan(S))
 
-  // Here we evaluate the forward transform explicitly and solve the reverse
-  // one by Newton's method.
+  // In Math::taupf and Math::tauf we evaluate the forward transform explicitly
+  // and solve the reverse one by Newton's method.
   //
-  // taupf and tauf are adapted from TransverseMercatorExact (taup and
-  // taupinv).  tau = tan(phi), taup = sinh(psi)
-  Math::real TransverseMercator::taupf(real tau) const {
-    if (!(abs(tau) < overflow())) {
-      // Fixed in 2015-02 to include the correct scale factor for large tau.
-      // This fixes the bug in Rhumb::GenInverse when one of the points is at a
-      // pole
-      real sig = sinh( eatanhe(real(1)) );
-      return tau / (Math::hypot(real(1), sig) + sig);
-    }
-    real
-      tau1 = Math::hypot(real(1), tau),
-      sig = sinh( eatanhe(tau / tau1) );
-    return Math::hypot(real(1), sig) * tau - sig * tau1;
-  }
-
-  Math::real TransverseMercator::tauf(real taup) const {
-    if (!(abs(taup) < overflow())) {
-      // Fixed in 2015-02 to match taupf.
-      real sig = sinh( eatanhe(real(1)) );
-      return taup * (Math::hypot(real(1), sig) + sig);
-    }
-    real
-      // To lowest order in e^2, taup = (1 - e^2) * tau = _e2m * tau; so use
-      // tau = taup/_e2m as a starting guess.  (This starting guess is the
-      // geocentric latitude which, to first order in the flattening, is equal
-      // to the conformal latitude.)  Only 1 iteration is needed for |lat| <
-      // 3.35 deg, otherwise 2 iterations are needed.  If, instead, tau = taup
-      // is used the mean number of iterations increases to 1.99 (2 iterations
-      // are needed except near tau = 0).
-      tau = taup/_e2m,
-      stol = tol_ * max(real(1), abs(taup));
-    // min iterations = 1, max iterations = 2; mean = 1.94
-    for (int i = 0; i < numit_ || GEOGRAPHICLIB_PANIC; ++i) {
-      real
-        tau1 = Math::hypot(real(1), tau),
-        sig = sinh( eatanhe( tau / tau1 ) ),
-        taupa = Math::hypot(real(1), sig) * tau - sig * tau1,
-        dtau = (taup - taupa) * (1 + _e2m * Math::sq(tau)) /
-        ( _e2m * tau1 * Math::hypot(real(1), taupa) );
-      tau += dtau;
-      if (!(abs(dtau) >= stol))
-        break;
-    }
-    return tau;
-  }
+  // There are adapted from TransverseMercatorExact (taup and taupinv).  tau =
+  // tan(phi), taup = sinh(psi)
 
   void TransverseMercator::Forward(real lon0, real lat, real lon,
                                    real& x, real& y, real& gamma, real& k)
@@ -362,7 +312,7 @@ namespace GeographicLib {
       real
         c = max(real(0), cos(lam)), // cos(pi/2) might be negative
         tau = tan(phi),
-        taup = taupf(tau);
+        taup = Math::taupf(tau, _es);
       xip = atan2(taup, c);
       // Used to be
       //   etap = Math::atanh(sin(lam) / cosh(psi));
@@ -370,7 +320,7 @@ namespace GeographicLib {
       // convergence and scale for Gauss-Schreiber TM (xip, etap) -- gamma0 =
       // atan(tan(xip) * tanh(etap)) = atan(tan(lam) * sin(phi'));
       // sin(phi') = tau'/sqrt(1 + tau'^2)
-      gamma = atan(tanx(lam) *
+      gamma = atan(Math::tand(lon) *
                    taup / Math::hypot(real(1), taup)); // Krueger p 22 (44)
       // k0 = sqrt(1 - _e2 * sin(phi)^2) * (cos(phi') / cos(phi)) * cosh(etap)
       // Note 1/cos(phi) = cosh(psip);
@@ -548,10 +498,10 @@ namespace GeographicLib {
       lam = atan2(s, c);        // Krueger p 17 (25)
       // Use Newton's method to solve for tau
       real
-        taup = sin(xip)/r,
-        tau = tauf(taup);
+        sxip = sin(xip),
+        tau = Math::tauf(sxip/r, _es);
+      gamma += atan2(sxip * tanh(etap), c); // Krueger p 19 (31)
       phi = atan(tau);
-      gamma += atan(tanx(xip) * tanh(etap)); // Krueger p 19 (31)
       // Note cos(phi') * cosh(eta') = r
       k *= sqrt(_e2m + _e2 * Math::sq(cos(phi))) *
         Math::hypot(real(1), tau) * r;
diff --git a/src/TransverseMercatorExact.cpp b/src/TransverseMercatorExact.cpp
index 66dc062..d5c0765 100644
--- a/src/TransverseMercatorExact.cpp
+++ b/src/TransverseMercatorExact.cpp
@@ -2,7 +2,7 @@
  * \file TransverseMercatorExact.cpp
  * \brief Implementation for GeographicLib::TransverseMercatorExact class
  *
- * Copyright (c) Charles Karney (2008-2014) <charles at karney.com> and licensed
+ * Copyright (c) Charles Karney (2008-2015) <charles at karney.com> and licensed
  * under the MIT/X11 License.  For more information, see
  * http://geographiclib.sourceforge.net/
  *
@@ -83,35 +83,6 @@ namespace GeographicLib {
     return utm;
   }
 
-  // tau = tan(phi), taup = sinh(psi)
-  Math::real TransverseMercatorExact::taup(real tau) const {
-    real
-      tau1 = Math::hypot(real(1), tau),
-      sig = sinh( _e * Math::atanh(_e * tau / tau1) );
-    return Math::hypot(real(1), sig) * tau - sig * tau1;
-  }
-
-  Math::real TransverseMercatorExact::taupinv(real taup) const {
-    real
-      // See comment in implementation of TransverseMercator::tauf about the
-      // initial guess
-      tau = taup/_mv,
-      stol = tol_ * max(real(1), abs(taup));
-    // min iterations = 1, max iterations = 2; mean = 1.94
-    for (int i = 0; i < numit_ || GEOGRAPHICLIB_PANIC; ++i) {
-      real
-        tau1 = Math::hypot(real(1), tau),
-        sig = sinh( _e * Math::atanh(_e * tau / tau1 ) ),
-        taupa = Math::hypot(real(1), sig) * tau - sig * tau1,
-        dtau = (taup - taupa) * (1 + _mv * Math::sq(tau)) /
-        ( _mv * tau1 * Math::hypot(real(1), taupa) );
-      tau += dtau;
-      if (!(abs(dtau) >= stol))
-        break;
-    }
-    return tau;
-  }
-
   void TransverseMercatorExact::zeta(real /*u*/, real snu, real cnu, real dnu,
                                      real /*v*/, real snv, real cnv, real dnv,
                                      real& taup, real& lam) const {
@@ -389,9 +360,8 @@ namespace GeographicLib {
       lon = 180 - lon;
     }
     real
-      phi = lat * Math::degree(),
       lam = lon * Math::degree(),
-      tau = tanx(phi);
+      tau = Math::tand(lat);
 
     // u,v = coordinates for the Thompson TM, Lee 54
     real u, v;
@@ -402,7 +372,8 @@ namespace GeographicLib {
       u = 0;
       v = _Ev.K();
     } else
-      zetainv(taup(tau), lam, u, v);
+      // tau = tan(phi), taup = sinh(psi)
+      zetainv(Math::taupf(tau, _e), lam, u, v);
 
     real snu, cnu, dnu, snv, cnv, dnv;
     _Eu.sncndn(u, snu, cnu, dnu);
@@ -421,7 +392,7 @@ namespace GeographicLib {
     } else {
       // Recompute (tau, lam) from (u, v) to improve accuracy of Scale
       zeta(u, snu, cnu, dnu, v, snv, cnv, dnv, tau, lam);
-      tau=taupinv(tau);
+      tau = Math::tauf(tau, _e);
       Scale(tau, lam, snu, cnu, dnu, snv, cnv, dnv, gamma, k);
       gamma /= Math::degree();
     }
@@ -463,7 +434,7 @@ namespace GeographicLib {
     real phi, lam, tau;
     if (v != 0 || u != _Eu.K()) {
       zeta(u, snu, cnu, dnu, v, snv, cnv, dnv, tau, lam);
-      tau = taupinv(tau);
+      tau = Math::tauf(tau, _e);
       phi = atan(tau);
       lat = phi / Math::degree();
       lon = lam / Math::degree();
diff --git a/src/UTMUPS.cpp b/src/UTMUPS.cpp
index de1f45a..494ea02 100644
--- a/src/UTMUPS.cpp
+++ b/src/UTMUPS.cpp
@@ -84,7 +84,7 @@ namespace GeographicLib {
         lon0 = CentralMeridian(zone1),
         dlon = lon - lon0;
       dlon = abs(dlon - 360 * floor((dlon + 180)/360));
-      if (dlon > 60)
+      if (!(dlon <= 60))
         // Check isn't really necessary because CheckCoords catches this case.
         // But this allows a more meaningful error message to be given.
         throw GeographicErr("Longitude " + Utility::str(lon)
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index e8b0034..16522ad 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -57,293 +57,5 @@ if (NOT WIN32)
   add_custom_target (scripts ALL DEPENDS ${SCRIPTS})
 endif ()
 
-# Turn on testing
-enable_testing ()
-
-# Here are the tests.  They consists of calling the various tools with
-# --input-string and matching the output against regular expressions.
-
-add_test (NAME GeoConvert0
-  COMMAND GeoConvert -p -3 -m --input-string "33.3 44.4")
-set_tests_properties (GeoConvert0
-  PROPERTIES PASS_REGULAR_EXPRESSION "38SMB4484")
-if (NOT GEOGRAPHICLIB_PRECISION EQUAL 4)
-  # I/O for boost-quad has a bug where precision 0 is interpreted as
-  # printed all the digits of the number (instead of printing the
-  # integer portion).
-  add_test (NAME GeoConvert1 COMMAND GeoConvert -d --input-string "38smb")
-  set_tests_properties (GeoConvert1
-    PROPERTIES PASS_REGULAR_EXPRESSION "32d59'14\\.1\"N 044d27'53\\.4\"E")
-endif ()
-add_test (NAME GeoConvert2
-  COMMAND GeoConvert -p -2 --input-string "30d30'30\" 30.50833")
-set_tests_properties (GeoConvert2
-  PROPERTIES PASS_REGULAR_EXPRESSION "30\\.508 30\\.508")
-add_test (NAME GeoConvert3 COMMAND GeoConvert --junk)
-set_tests_properties (GeoConvert3 PROPERTIES WILL_FAIL ON)
-add_test (NAME GeoConvert4 COMMAND GeoConvert --input-string garbage)
-set_tests_properties (GeoConvert4 PROPERTIES WILL_FAIL ON)
-# Check fix for DMS::Decode bug fixed on 2011-03-22
-add_test (NAME GeoConvert5 COMMAND GeoConvert --input-string "5d. 0")
-set_tests_properties (GeoConvert5 PROPERTIES WILL_FAIL ON)
-if (NOT (MSVC AND MSVC_VERSION MATCHES "1[78].."))
-  # Check fix for DMS::Decode double rounding bug fixed on 2012-11-15
-  # This test is known to fail for VS 11 and 12 bug reported 2013-01-10
-  # http://connect.microsoft.com/VisualStudio/feedback/details/776287
-  # OK to skip this test for these compilers because this is a question
-  # of accuracy of the least significant bit.  The bug is fixed in VS 14.
-  add_test (NAME GeoConvert6 COMMAND GeoConvert -p 9
-    --input-string "0 179.99999999999998578")
-  set_tests_properties (GeoConvert6
-    PROPERTIES PASS_REGULAR_EXPRESSION  "179\\.9999999999999[7-9]")
-endif ()
-
-add_test (NAME GeodSolve0 COMMAND
-  GeodSolve -i -p 0 --input-string "40.6 -73.8 49d01'N 2d33'E")
-set_tests_properties (GeodSolve0
-  PROPERTIES PASS_REGULAR_EXPRESSION "53\\.47022 111\\.59367 5853226")
-add_test (NAME GeodSolve1 COMMAND
-  GeodSolve -p 0 --input-string "40d38'23\"N 073d46'44\"W 53d30' 5850e3")
-set_tests_properties (GeodSolve1
-  PROPERTIES PASS_REGULAR_EXPRESSION "49\\.01467 2\\.56106 111\\.62947")
-# Check fix for antipodal prolate bug found 2010-09-04
-add_test (NAME GeodSolve2 COMMAND
-  GeodSolve -i -p 0 -e 6.4e6 -1/150 --input-string "0.07476 0 -0.07476 180")
-set_tests_properties (GeodSolve2
-  PROPERTIES PASS_REGULAR_EXPRESSION "90\\.00078 90\\.00078 20106193")
-# Another check for similar bug
-add_test (NAME GeodSolve3 COMMAND
-  GeodSolve -i -p 0 -e 6.4e6 -1/150 --input-string "0.1 0 -0.1 180")
-set_tests_properties (GeodSolve3
-  PROPERTIES PASS_REGULAR_EXPRESSION "90\\.00105 90\\.00105 20106193")
-# Check fix for short line bug found 2010-05-21
-add_test (NAME GeodSolve4 COMMAND
-  GeodSolve -i --input-string "36.493349428792 0 36.49334942879201 .0000008")
-set_tests_properties (GeodSolve4
-  PROPERTIES PASS_REGULAR_EXPRESSION ".* .* 0\\.072")
-# Check fix for point2=pole bug found 2010-05-03 (but only with long double)
-add_test (NAME GeodSolve5
-  COMMAND GeodSolve -p 0 --input-string "0.01777745589997 30 0 10e6")
-set_tests_properties (GeodSolve5
-  PROPERTIES PASS_REGULAR_EXPRESSION
-  "90\\.00000 -150\\.00000 -180\\.00000;90\\.00000 30\\.00000 0\\.00000")
-
-# Check fix for volatile sbet12a bug found 2011-06-25 (gcc 4.4.4 x86 -O3)
-# Found again on 2012-03-27 with tdm-mingw32 (g++ 4.6.1).
-add_test (NAME GeodSolve6 COMMAND GeodSolve -i --input-string
-  "88.202499451857 0 -88.202499451857 179.981022032992859592")
-add_test (NAME GeodSolve7 COMMAND GeodSolve -i --input-string
-  "89.262080389218 0 -89.262080389218 179.992207982775375662")
-add_test (NAME GeodSolve8 COMMAND GeodSolve -i --input-string
-  "89.333123580033 0 -89.333123580032997687 179.99295812360148422")
-set_tests_properties (GeodSolve6
-  PROPERTIES PASS_REGULAR_EXPRESSION ".* .* 20003898.214")
-set_tests_properties (GeodSolve7
-  PROPERTIES PASS_REGULAR_EXPRESSION ".* .* 20003925.854")
-set_tests_properties (GeodSolve8
-  PROPERTIES PASS_REGULAR_EXPRESSION ".* .* 20003926.881")
-
-# Check fix for volatile x bug found 2011-06-25 (gcc 4.4.4 x86 -O3)
-add_test (NAME GeodSolve9 COMMAND GeodSolve -i --input-string
-  "56.320923501171 0 -56.320923501171 179.664747671772880215")
-set_tests_properties (GeodSolve9
-  PROPERTIES PASS_REGULAR_EXPRESSION ".* .* 19993558.287")
-
-# Check fix for adjust tol1_ bug found 2011-06-25 (Visual Studio 10 rel + debug)
-add_test (NAME GeodSolve10 COMMAND GeodSolve -i --input-string
-  "52.784459512564 0 -52.784459512563990912 179.634407464943777557")
-set_tests_properties (GeodSolve10
-  PROPERTIES PASS_REGULAR_EXPRESSION ".* .* 19991596.095")
-
-# Check fix for bet2 = -bet1 bug found 2011-06-25 (Visual Studio 10 rel + debug)
-add_test (NAME GeodSolve11 COMMAND GeodSolve -i --input-string
-  "48.522876735459 0 -48.52287673545898293 179.599720456223079643")
-set_tests_properties (GeodSolve11
-  PROPERTIES PASS_REGULAR_EXPRESSION ".* .* 19989144.774")
-
-# Check fix for inverse geodesics on extreme prolate/oblate ellipsoids
-# Reported 2012-08-29 Stefan Guenther <stefan.gunther at embl.de>; fixed 2012-10-07
-add_test (NAME GeodSolve12 COMMAND
-  GeodSolve -i -e 89.8 -1.83 -p 1 --input-string "0 0 -10 160")
-add_test (NAME GeodSolve13 COMMAND
-  GeodSolve -i -e 89.8 -1.83 -p 1 --input-string "0 0 -10 160" -E)
-set_tests_properties (GeodSolve12 GeodSolve13
-  PROPERTIES PASS_REGULAR_EXPRESSION "120\\.27.* 105\\.15.* 266\\.7")
-
-# Check fix for inverse ignoring lon12 = nan
-add_test (NAME GeodSolve14 COMMAND GeodSolve -i --input-string "0 0 1 nan")
-set_tests_properties (GeodSolve14
-  PROPERTIES PASS_REGULAR_EXPRESSION "nan nan nan")
-
-# Check fix for pole-encircling bug found 2011-03-16
-add_test (NAME Planimeter0
-  COMMAND Planimeter --input-string "89 0;89 90;89 180;89 270")
-add_test (NAME Planimeter1 COMMAND
-  Planimeter -r --input-string "-89 0;-89 90;-89 180;-89 270")
-add_test (NAME Planimeter2
-  COMMAND Planimeter --input-string "0 -1;-1 0;0 1;1 0")
-add_test (NAME Planimeter3 COMMAND Planimeter --input-string "90 0; 0 0; 0 90")
-add_test (NAME Planimeter4
-  COMMAND Planimeter -l --input-string "90 0; 0 0; 0 90")
-set_tests_properties (Planimeter0
-  PROPERTIES PASS_REGULAR_EXPRESSION
-  "4 631819\\.8745[0-9]+ 2495230567[78]\\.[0-9]+")
-set_tests_properties (Planimeter1
-  PROPERTIES PASS_REGULAR_EXPRESSION
-  "4 631819\\.8745[0-9]+ 2495230567[78]\\.[0-9]+")
-set_tests_properties (Planimeter2
-  PROPERTIES PASS_REGULAR_EXPRESSION "4 627598\\.2731[0-9]+ 24619419146.[0-9]+")
-set_tests_properties (Planimeter3
-  PROPERTIES PASS_REGULAR_EXPRESSION
-  "3 30022685\\.[0-9]+ 63758202715511\\.[0-9]+")
-set_tests_properties (Planimeter4
-  PROPERTIES PASS_REGULAR_EXPRESSION "3 20020719\\.[0-9]+")
-# Check fix for Planimeter pole crossing bug found 2011-06-24
-add_test (NAME Planimeter5
-  COMMAND Planimeter --input-string "89,0.1;89,90.1;89,-179.9")
-set_tests_properties (Planimeter5
-  PROPERTIES PASS_REGULAR_EXPRESSION
-  "3 539297\\.[0-9]+ 1247615283[89]\\.[0-9]+")
-# Check fix for Planimeter lon12 rounding bug found 2012-12-03
-add_test (NAME Planimeter6
-  COMMAND Planimeter -p 8 --input-string "9 -0.00000000000001;9 180;9 0")
-add_test (NAME Planimeter7
-  COMMAND Planimeter -p 8 --input-string "9  0.00000000000001;9 0;9 180")
-add_test (NAME Planimeter8
-  COMMAND Planimeter -p 8 --input-string "9  0.00000000000001;9 180;9 0")
-add_test (NAME Planimeter9
-  COMMAND Planimeter -p 8 --input-string "9 -0.00000000000001;9 0;9 180")
-set_tests_properties (Planimeter6 Planimeter7 Planimeter8 Planimeter9
-  PROPERTIES PASS_REGULAR_EXPRESSION "3 36026861\\.[0-9]+ -?0.0[0-9]+")
-# Area of Wyoming
-add_test (NAME Planimeter10 COMMAND Planimeter -R
-  --input-string "41N 111:3W; 41N 104:3W; 45N 104:3W; 45N 111:3W")
-set_tests_properties (Planimeter10
-  PROPERTIES PASS_REGULAR_EXPRESSION "4 2029616.[0-9]+ 2535883763..\\.")
-# Area of arctic circle
-add_test (NAME Planimeter11
-  COMMAND Planimeter -R --input-string "66:33:44 0; 66:33:44 180")
-set_tests_properties (Planimeter11
-  PROPERTIES PASS_REGULAR_EXPRESSION "2 15985058.[0-9]+ 212084182523..\\.")
-add_test (NAME Planimeter12
-  COMMAND Planimeter --input-string "66:33:44 0; 66:33:44 180")
-set_tests_properties (Planimeter12
-  PROPERTIES PASS_REGULAR_EXPRESSION "2 10465729.[0-9]+ -?0.0")
-
-# Check fix for AlbersEqualArea::Reverse bug found 2011-05-01
-add_test (NAME ConicProj0 COMMAND
-  ConicProj -a 40d58 39d56 -l 77d45W -r --input-string "220e3 -52e3")
-set_tests_properties (ConicProj0
-  PROPERTIES PASS_REGULAR_EXPRESSION
-  "39\\.95[0-9]+ -75\\.17[0-9]+ 1\\.67[0-9]+ 0\\.99[0-9]+")
-# Check fix for AlbersEqualArea prolate bug found 2012-05-15
-add_test (NAME ConicProj1 COMMAND
-  ConicProj -a 0 0 -e 6.4e6 -0.5 -r --input-string "0 8605508")
-set_tests_properties (ConicProj1
-  PROPERTIES PASS_REGULAR_EXPRESSION "^85\\.00")
-# Check fix for LambertConformalConic::Forward bug found 2012-07-14
-add_test (NAME ConicProj2 COMMAND ConicProj -c -30 -30 --input-string "-30 0")
-set_tests_properties (ConicProj2
-  PROPERTIES PASS_REGULAR_EXPRESSION "^-?0\\.0+ -?0\\.0+ -?0\\.0+ 1\\.0+")
-# Check fixes for LambertConformalConic::Reverse overflow bugs found 2012-07-14
-add_test (NAME ConicProj3
-  COMMAND ConicProj -r -c 0 0 --input-string "1113195 -1e10")
-set_tests_properties (ConicProj3
-  PROPERTIES PASS_REGULAR_EXPRESSION "^-90\\.0+ 10\\.00[0-9]+ ")
-add_test (NAME ConicProj4
-  COMMAND ConicProj -r -c 0 0 --input-string "1113195 inf")
-set_tests_properties (ConicProj4
-  PROPERTIES PASS_REGULAR_EXPRESSION "^90\\.0+ 10\\.00[0-9]+ ")
-add_test (NAME ConicProj5
-  COMMAND ConicProj -r -c 45 45 --input-string "0 -1e100")
-set_tests_properties (ConicProj5
-  PROPERTIES PASS_REGULAR_EXPRESSION "^-90\\.0+ -?0\\.00[0-9]+ ")
-add_test (NAME ConicProj6 COMMAND ConicProj -r -c 45 45 --input-string "0 -inf")
-set_tests_properties (ConicProj6
-  PROPERTIES PASS_REGULAR_EXPRESSION "^-90\\.0+ -?0\\.00[0-9]+ ")
-add_test (NAME ConicProj7
-  COMMAND ConicProj -r -c 90 90 --input-string "0 -1e150")
-set_tests_properties (ConicProj7
-  PROPERTIES PASS_REGULAR_EXPRESSION "^-90\\.0+ -?0\\.00[0-9]+ ")
-add_test (NAME ConicProj8 COMMAND ConicProj -r -c 90 90 --input-string "0 -inf")
-set_tests_properties (ConicProj8
-  PROPERTIES PASS_REGULAR_EXPRESSION "^-90\\.0+ -?0\\.00[0-9]+ ")
-
-add_test (NAME CartConvert0 COMMAND
-  CartConvert -e 6.4e6 1/100 -r --input-string "10e3 0 1e3")
-add_test (NAME CartConvert1 COMMAND
-  CartConvert -e 6.4e6 -1/100 -r --input-string "1e3 0 10e3")
-set_tests_properties (CartConvert0
-  PROPERTIES PASS_REGULAR_EXPRESSION
-  "85\\.57[0-9]+ 0\\.0[0]+ -6334614\\.[0-9]+")
-set_tests_properties (CartConvert1
-  PROPERTIES PASS_REGULAR_EXPRESSION
-  "4\\.42[0-9]+ 0\\.0[0]+ -6398614\\.[0-9]+")
-
-# Test fix to bad meridian convergence at pole with
-# TransverseMercatorExact found 2013-06-26
-add_test (NAME TransverseMercatorProj0 COMMAND
-  TransverseMercatorProj -k 1 --input-string "90 75")
-set_tests_properties (TransverseMercatorProj0
-  PROPERTIES PASS_REGULAR_EXPRESSION
-  "^0\\.0+ 10001965\\.7293[0-9]+ 75\\.0+ 1\\.0+")
-# Test fix to bad scale at pole with TransverseMercatorExact
-# found 2013-06-30 (quarter meridian = 10001965.7293127228128889202m)
-add_test (NAME TransverseMercatorProj1 COMMAND
-  TransverseMercatorProj -k 1 -r --input-string "0 10001965.7293127228")
-set_tests_properties (TransverseMercatorProj1
-  PROPERTIES PASS_REGULAR_EXPRESSION
-  "(90\\.0+ 0\\.0+ 0\\.0+|(90\\.0+|89\\.99999999999[0-9]+) -?180\\.0+ -?180\\.0+) (1\\.0000+|0\\.9999+)")
-
-# Test fix to bad handling of pole by RhumbSolve -i
-# Reported  2015-02-24 by Thomas Murray <thomas.murray56 at gmail.com>;
-add_test (NAME RhumbSolve0 COMMAND
-  RhumbSolve -p 3 -i --input-string "0 0 90 0")
-set_tests_properties (RhumbSolve0
-  PROPERTIES PASS_REGULAR_EXPRESSION "^0\\.0+ 10001965\\.729 ")
-
-if (EXISTS ${GEOGRAPHICLIB_DATA}/geoids/egm96-5.pgm)
-  # Check fix for single-cell cache bug found 2010-11-23
-  add_test (NAME GeoidEval0
-    COMMAND GeoidEval -n egm96-5 --input-string "0d1 0d1;0d4 0d4")
-  set_tests_properties (GeoidEval0
-    PROPERTIES PASS_REGULAR_EXPRESSION "^17\\.1[56]..\n17\\.1[45]..")
-endif ()
-
-if (EXISTS ${GEOGRAPHICLIB_DATA}/magnetic/wmm2010.wmm)
-  # Test case from WMM2010_Report.pdf, Sec 1.5, pp 14-15:
-  # t = 2012.5, lat = -80, lon = 240, h = 100e3
-  add_test (NAME MagneticField0 COMMAND
-    MagneticField -n wmm2010 -p 10 -r --input-string "2012.5 -80 240 100e3")
-  add_test (NAME MagneticField1 COMMAND
-    MagneticField -n wmm2010 -p 10 -r -t 2012.5 --input-string "-80 240 100e3")
-  add_test (NAME MagneticField2 COMMAND
-    MagneticField -n wmm2010 -p 10 -r -c 2012.5 -80 100e3 --input-string "240")
-  set_tests_properties (MagneticField0
-    PROPERTIES PASS_REGULAR_EXPRESSION
-    " 5535\\.5249148687 14765\\.3703243050 -50625\\.9305478794 .*\n.* 20\\.4904268023 1\\.0272592716 83\\.5313962281 ")
-  set_tests_properties (MagneticField1
-    PROPERTIES PASS_REGULAR_EXPRESSION
-    " 5535\\.5249148687 14765\\.3703243050 -50625\\.9305478794 .*\n.* 20\\.4904268023 1\\.0272592716 83\\.5313962281 ")
-  set_tests_properties (MagneticField2
-    PROPERTIES PASS_REGULAR_EXPRESSION
-    " 5535\\.5249148687 14765\\.3703243050 -50625\\.9305478794 .*\n.* 20\\.4904268023 1\\.0272592716 83\\.5313962281 ")
-endif ()
-
-if (EXISTS ${GEOGRAPHICLIB_DATA}/gravity/egm2008.egm)
-  # Verify no overflow at poles with high degree model
-  add_test (NAME Gravity0
-    COMMAND Gravity -n egm2008 -p 6 --input-string "90 110 0")
-  set_tests_properties (Gravity0
-    PROPERTIES PASS_REGULAR_EXPRESSION "-0\\.000146 0\\.000078 -9\\.832294")
-  # Check fix for invR bug in GravityCircle found by Mathieu Peyrega on
-  # 2013-04-09
-  add_test (NAME Gravity1
-    COMMAND Gravity -n egm2008 -A -c -18 4000 --input-string "-86")
-  set_tests_properties (Gravity1
-    PROPERTIES PASS_REGULAR_EXPRESSION "-7\\.438 1\\.305 -1\\.563")
-  add_test (NAME Gravity2
-    COMMAND Gravity -n egm2008 -D -c -18 4000 --input-string "-86")
-  set_tests_properties (Gravity2
-    PROPERTIES PASS_REGULAR_EXPRESSION "7\\.404 -6\\.168 7\\.616")
-endif ()
+# The test suite -- split into a separate file because it's rather large.
+include (tests.cmake)
diff --git a/tools/Makefile.am b/tools/Makefile.am
index cf53fc9..2023dfa 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -157,6 +157,6 @@ geographiclib-get-magnetic: geographiclib-get-magnetic.sh
 	chmod +x $@
 
 CLEANFILES = $(sbin_SCRIPTS)
-EXTRA_DIST = Makefile.mk CMakeLists.txt \
+EXTRA_DIST = Makefile.mk CMakeLists.txt tests.cmake \
 	geographiclib-get-geoids.sh geographiclib-get-gravity.sh \
 	geographiclib-get-magnetic.sh
diff --git a/tools/Makefile.in b/tools/Makefile.in
index 5d42efa..0a19dd4 100644
--- a/tools/Makefile.in
+++ b/tools/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994-2013 Free Software Foundation, Inc.
@@ -547,7 +547,7 @@ sbin_SCRIPTS = geographiclib-get-geoids \
 
 geographiclib_data = $(datadir)/GeographicLib
 CLEANFILES = $(sbin_SCRIPTS)
-EXTRA_DIST = Makefile.mk CMakeLists.txt \
+EXTRA_DIST = Makefile.mk CMakeLists.txt tests.cmake \
 	geographiclib-get-geoids.sh geographiclib-get-gravity.sh \
 	geographiclib-get-magnetic.sh
 
diff --git a/tools/CMakeLists.txt b/tools/tests.cmake
similarity index 81%
copy from tools/CMakeLists.txt
copy to tools/tests.cmake
index e8b0034..603df1a 100644
--- a/tools/CMakeLists.txt
+++ b/tools/tests.cmake
@@ -1,80 +1,25 @@
-# Build the tools...
+# Here are the tests for GeographicLib
 
-# Where to find the *.usage files for the --help option.
-include_directories (${PROJECT_BINARY_DIR}/man)
-# Only needed if target_compile_definitions is not supported
-add_definitions (${PROJECT_DEFINITIONS})
-
-# Loop over all the tools, specifying the source and library.
-add_custom_target (tools ALL)
-foreach (TOOL ${TOOLS})
-
-  add_executable (${TOOL} ${TOOL}.cpp)
-  if (MAINTAINER)
-    add_dependencies (${TOOL} usage)
-  endif ()
-  add_dependencies (tools ${TOOL})
-
-  set_source_files_properties (${TOOL}.cpp PROPERTIES
-    OBJECT_DEPENDS ${PROJECT_BINARY_DIR}/man/${TOOL}.usage)
-
-  target_link_libraries (${TOOL} ${PROJECT_LIBRARIES}
-    ${QUAD_LIBRARIES} ${MPFR_LIBRARIES})
-
-endforeach ()
-
-if (MSVC OR CMAKE_CONFIGURATION_TYPES)
-  # Add _d suffix for your debug versions of the tools
-  set_target_properties (${TOOLS} PROPERTIES
-    DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
-endif ()
-
-if (APPLE AND NOT CMAKE_VERSION VERSION_LESS 2.8.12)
-  # Ensure that the package is relocatable
-  set_target_properties (${TOOLS} PROPERTIES
-    INSTALL_RPATH "@loader_path/../lib${LIB_SUFFIX}")
-endif ()
-
-# Specify where the tools are installed, adding them to the export targets
-install (TARGETS ${TOOLS} EXPORT targets DESTINATION bin)
-
-# Put all the tools into a folder in the IDE
-set_property (TARGET tools ${TOOLS} PROPERTY FOLDER tools)
-
-# Create the scripts for downloading the data files on non-Windows
-# systems.  This needs to substitute ${GEOGRAPHICLIB_DATA} as the
-# default data directory.  These are installed under sbin, because it is
-# expected to be run with write access to /usr/local.
-if (NOT WIN32)
-  foreach (SCRIPT ${SCRIPTS})
-    configure_file (${SCRIPT}.sh scripts/${SCRIPT} @ONLY)
-    add_custom_command (OUTPUT ${SCRIPT}
-      COMMAND ${CMAKE_COMMAND} -E
-        copy scripts/${SCRIPT} ${SCRIPT} && chmod +x ${SCRIPT}
-      DEPENDS ${SCRIPT}.sh)
-    install (PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${SCRIPT} DESTINATION sbin)
-  endforeach ()
-  add_custom_target (scripts ALL DEPENDS ${SCRIPTS})
-endif ()
-
-# Turn on testing
+# First turn on testing
 enable_testing ()
 
-# Here are the tests.  They consists of calling the various tools with
-# --input-string and matching the output against regular expressions.
+# The tests consist of calling the various tools with --input-string and
+# matching the output against regular expressions.
 
 add_test (NAME GeoConvert0
   COMMAND GeoConvert -p -3 -m --input-string "33.3 44.4")
 set_tests_properties (GeoConvert0
   PROPERTIES PASS_REGULAR_EXPRESSION "38SMB4484")
-if (NOT GEOGRAPHICLIB_PRECISION EQUAL 4)
-  # I/O for boost-quad has a bug where precision 0 is interpreted as
-  # printed all the digits of the number (instead of printing the
-  # integer portion).
-  add_test (NAME GeoConvert1 COMMAND GeoConvert -d --input-string "38smb")
-  set_tests_properties (GeoConvert1
-    PROPERTIES PASS_REGULAR_EXPRESSION "32d59'14\\.1\"N 044d27'53\\.4\"E")
-endif ()
+
+# I/O for boost-quadmath has a bug where precision 0 is interpreted as
+# printed all the digits of the number (instead of printing the integer
+# portion).  Problem reported on 2014-06-07:
+# https://svn.boost.org/trac/boost/ticket/10103.  GeographicLib 1.42
+# includes a workaround for this bug.
+add_test (NAME GeoConvert1 COMMAND GeoConvert -d --input-string "38smb")
+set_tests_properties (GeoConvert1
+  PROPERTIES PASS_REGULAR_EXPRESSION "32d59'14\\.1\"N 044d27'53\\.4\"E")
+
 add_test (NAME GeoConvert2
   COMMAND GeoConvert -p -2 --input-string "30d30'30\" 30.50833")
 set_tests_properties (GeoConvert2
@@ -170,10 +115,27 @@ add_test (NAME GeodSolve13 COMMAND
 set_tests_properties (GeodSolve12 GeodSolve13
   PROPERTIES PASS_REGULAR_EXPRESSION "120\\.27.* 105\\.15.* 266\\.7")
 
-# Check fix for inverse ignoring lon12 = nan
-add_test (NAME GeodSolve14 COMMAND GeodSolve -i --input-string "0 0 1 nan")
-set_tests_properties (GeodSolve14
-  PROPERTIES PASS_REGULAR_EXPRESSION "nan nan nan")
+if (NOT GEOGRAPHICLIB_PRECISION EQUAL 4)
+  # mpfr (nan == 0 is true) and boost-quadmath (nan > 0 is true) have
+  # bugs in handling nans, so skip this test.  Problems reported on
+  # 2015-03-31, https://svn.boost.org/trac/boost/ticket/11159.  MFPR C++
+  # version 3.6.2 fixes its nan problem.
+  #
+  # Check fix for inverse ignoring lon12 = nan
+  add_test (NAME GeodSolve14 COMMAND GeodSolve -i --input-string "0 0 1 nan")
+  set_tests_properties (GeodSolve14
+    PROPERTIES PASS_REGULAR_EXPRESSION "nan nan nan")
+endif()
+
+# Initial implementation of Math::eatanhe was wrong for e^2 < 0.  This
+# checks that this is fixed.
+add_test (NAME GeodSolve15 COMMAND
+  GeodSolve -e 6.4e6 -1/150 -f --input-string "1 2 3 4")
+add_test (NAME GeodSolve16 COMMAND
+  GeodSolve -e 6.4e6 -1/150 -f --input-string "1 2 3 4" -E)
+set_tests_properties (GeodSolve15 GeodSolve16
+  PROPERTIES PASS_REGULAR_EXPRESSION
+  "1\\..* 2\\..* 3\\..* 1\\..* 2\\..* 3\\..* 4\\..* 0\\..* 4\\..* 1\\..* 1\\..* 23700")
 
 # Check fix for pole-encircling bug found 2011-03-16
 add_test (NAME Planimeter0
@@ -219,16 +181,21 @@ set_tests_properties (Planimeter6 Planimeter7 Planimeter8 Planimeter9
 add_test (NAME Planimeter10 COMMAND Planimeter -R
   --input-string "41N 111:3W; 41N 104:3W; 45N 104:3W; 45N 111:3W")
 set_tests_properties (Planimeter10
-  PROPERTIES PASS_REGULAR_EXPRESSION "4 2029616.[0-9]+ 2535883763..\\.")
+  PROPERTIES PASS_REGULAR_EXPRESSION "4 2029616\\.[0-9]+ 2535883763..\\.")
 # Area of arctic circle
 add_test (NAME Planimeter11
   COMMAND Planimeter -R --input-string "66:33:44 0; 66:33:44 180")
 set_tests_properties (Planimeter11
-  PROPERTIES PASS_REGULAR_EXPRESSION "2 15985058.[0-9]+ 212084182523..\\.")
+  PROPERTIES PASS_REGULAR_EXPRESSION "2 15985058\\.[0-9]+ 212084182523..\\.")
 add_test (NAME Planimeter12
   COMMAND Planimeter --input-string "66:33:44 0; 66:33:44 180")
 set_tests_properties (Planimeter12
-  PROPERTIES PASS_REGULAR_EXPRESSION "2 10465729.[0-9]+ -?0.0")
+  PROPERTIES PASS_REGULAR_EXPRESSION "2 10465729\\.[0-9]+ -?0.0")
+# Check encircling pole twice
+add_test (NAME Planimeter13 COMMAND
+  Planimeter --input-string "89 -360; 89 -240; 89 -120; 89 0; 89 120; 89 240")
+set_tests_properties (Planimeter13
+  PROPERTIES PASS_REGULAR_EXPRESSION "6 1160741\\..* 32415230256\\.")
 
 # Check fix for AlbersEqualArea::Reverse bug found 2011-05-01
 add_test (NAME ConicProj0 COMMAND
@@ -299,7 +266,9 @@ set_tests_properties (TransverseMercatorProj1
 # Reported  2015-02-24 by Thomas Murray <thomas.murray56 at gmail.com>;
 add_test (NAME RhumbSolve0 COMMAND
   RhumbSolve -p 3 -i --input-string "0 0 90 0")
-set_tests_properties (RhumbSolve0
+add_test (NAME RhumbSolve1 COMMAND
+  RhumbSolve -p 3 -i --input-string "0 0 90 0" -s)
+set_tests_properties (RhumbSolve0 RhumbSolve1
   PROPERTIES PASS_REGULAR_EXPRESSION "^0\\.0+ 10001965\\.729 ")
 
 if (EXISTS ${GEOGRAPHICLIB_DATA}/geoids/egm96-5.pgm)
diff --git a/windows/Geographic-vc10.vcxproj b/windows/Geographic-vc10.vcxproj
index db2355f..eda7fc7 100644
--- a/windows/Geographic-vc10.vcxproj
+++ b/windows/Geographic-vc10.vcxproj
@@ -206,6 +206,7 @@
     <ClCompile Include="../src/MGRS.cpp" />
     <ClCompile Include="../src/MagneticCircle.cpp" />
     <ClCompile Include="../src/MagneticModel.cpp" />
+    <ClCompile Include="../src/Math.cpp" />
     <ClCompile Include="../src/NormalGravity.cpp" />
     <ClCompile Include="../src/OSGB.cpp" />
     <ClCompile Include="../src/PolarStereographic.cpp" />
diff --git a/windows/Geographic-vc10x.vcxproj b/windows/Geographic-vc10x.vcxproj
index 443d979..19a9682 100644
--- a/windows/Geographic-vc10x.vcxproj
+++ b/windows/Geographic-vc10x.vcxproj
@@ -142,6 +142,7 @@
     <ClCompile Include="../src/MGRS.cpp" />
     <ClCompile Include="../src/MagneticCircle.cpp" />
     <ClCompile Include="../src/MagneticModel.cpp" />
+    <ClCompile Include="../src/Math.cpp" />
     <ClCompile Include="../src/NormalGravity.cpp" />
     <ClCompile Include="../src/OSGB.cpp" />
     <ClCompile Include="../src/PolarStereographic.cpp" />
diff --git a/windows/Geographic-vc13n.vcxproj b/windows/Geographic-vc13n.vcxproj
index 6516063..f048a58 100644
--- a/windows/Geographic-vc13n.vcxproj
+++ b/windows/Geographic-vc13n.vcxproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
     <ProjectConfiguration Include="Debug|Win32">
@@ -210,6 +210,7 @@
     <ClCompile Include="../src/MGRS.cpp" />
     <ClCompile Include="../src/MagneticCircle.cpp" />
     <ClCompile Include="../src/MagneticModel.cpp" />
+    <ClCompile Include="../src/Math.cpp" />
     <ClCompile Include="../src/NormalGravity.cpp" />
     <ClCompile Include="../src/OSGB.cpp" />
     <ClCompile Include="../src/PolarStereographic.cpp" />
@@ -224,4 +225,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/windows/Geographic-vc8.vcproj b/windows/Geographic-vc8.vcproj
index 08fc999..ea5a88f 100644
--- a/windows/Geographic-vc8.vcproj
+++ b/windows/Geographic-vc8.vcproj
@@ -361,6 +361,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\src\Math.cpp"
+				>
+			</File>
+			<File
 				RelativePath="..\src\NormalGravity.cpp"
 				>
 			</File>
diff --git a/windows/Geographic-vc9.vcproj b/windows/Geographic-vc9.vcproj
index 1f50ddc..6d03e0a 100644
--- a/windows/Geographic-vc9.vcproj
+++ b/windows/Geographic-vc9.vcproj
@@ -364,6 +364,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\src\Math.cpp"
+				>
+			</File>
+			<File
 				RelativePath="..\src\NormalGravity.cpp"
 				>
 			</File>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/geographiclib.git



More information about the Pkg-grass-devel mailing list