]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Avoid boost functions that don't work on BSDs. 2262/head
authorDavid Wells <wellsd2@rpi.edu>
Sun, 28 Feb 2016 21:08:06 +0000 (16:08 -0500)
committerDavid Wells <wellsd2@rpi.edu>
Sun, 28 Feb 2016 21:25:06 +0000 (16:25 -0500)
As was noted in issue #2261, the function boost::math::iround cannot be
used on some BSD variants due to the following compilation error:

In file included from /root/workspace/dealii/source/lac/lapack_full_matrix.cc:25:
In file included from /usr/local/include/boost/math/special_functions/round.hpp:15:
In file included from /usr/local/include/boost/math/special_functions/fpclassify.hpp:19:
In file included from /usr/local/include/boost/math/special_functions/math_fwd.hpp:26:
In file included from /usr/local/include/boost/math/special_functions/detail/round_fwd.hpp:12:
/usr/local/include/boost/math/tools/promotion.hpp:141:10: error: static_assert failed
"Sorry, but this platform does not have sufficient long double support for the special functions to be reliably implemented."
         BOOST_STATIC_ASSERT_MSG((0 == ::boost::is_same<type, long
         double>::value),
         "Sorry, but this platform does not have sufficient long double support for the special functions to be reliably implement ed.");
/usr/local/include/boost/static_assert.hpp:31:45: note: expanded from macro 'BOOST_STATIC_ASSERT_MSG'

Since we only use iround for clarity this is not hard to work around.

A note on the implementation: LAPACK functions can usually be run in two
different modes. In the first, they compute the optimal size of the work
array. In the second they actually execute the function. Therefore
all we need to do is make the work arrays one longer and we should still
get the same performance out of LAPACK without needing to worry about
any unforeseen roundoff issues.

source/lac/lapack_full_matrix.cc

index 52faaca1503444c99fb64ef45791197d98e71ab6..c6f79ba36c423265839f1b50230d36ef21c8b398 100644 (file)
@@ -22,8 +22,6 @@
 #include <deal.II/lac/vector.h>
 #include <deal.II/lac/block_vector.h>
 
-#include <boost/math/special_functions/round.hpp>
-
 #include <iostream>
 #include <iomanip>
 
@@ -504,8 +502,9 @@ LAPACKFullMatrix<number>::compute_svd()
         &wr[0], mu, &mm, mvt, &nn,
         &work[0], &lwork, &ipiv[0], &info);
   AssertThrow (info==0, LAPACKSupport::ExcErrorCode("gesdd", info));
-  // Now resize work array and
-  lwork = boost::math::iround(work[0]);
+  // Resize the work array. Add one to the size computed by LAPACK to be on
+  // the safe side.
+  lwork = static_cast<int>(work[0] + 1);
 
   work.resize(lwork);
   // Do the actual SVD.
@@ -656,8 +655,9 @@ LAPACKFullMatrix<number>::compute_eigenvalues(const bool right,
   // geev returns info=0 on success. Since we only queried the optimal size
   // for work, everything else would not be acceptable.
   Assert (info == 0, ExcInternalError());
-  // Allocate working array according to suggestion.
-  lwork = boost::math::iround(work[0]);
+  // Allocate working array according to suggestion (same strategy as was
+  // noted in compute_svd).
+  lwork = static_cast<int>(work[0] + 1);
 
   // resize workspace array
   work.resize((size_type ) lwork);
@@ -728,8 +728,9 @@ LAPACKFullMatrix<number>::compute_eigenvalues_symmetric(const number        lowe
   // syevx returns info=0 on success. Since we only queried the optimal size
   // for work, everything else would not be acceptable.
   Assert (info == 0, ExcInternalError());
-  // Allocate working array according to suggestion.
-  lwork = boost::math::iround(work[0]);
+  // Allocate working array according to suggestion (same strategy as was noted in
+  // compute_svd).
+  lwork = static_cast<int>(work[0] + 1);
   work.resize(static_cast<size_type> (lwork));
 
   // Finally compute the eigenvalues.
@@ -818,8 +819,9 @@ LAPACKFullMatrix<number>::compute_generalized_eigenvalues_symmetric(
   // sygvx returns info=0 on success. Since we only queried the optimal size
   // for work, everything else would not be acceptable.
   Assert (info == 0, ExcInternalError());
-  // Allocate working array according to suggestion.
-  lwork = boost::math::iround(work[0]);
+  // Allocate working array according to suggestion (same strategy as was
+  // noted in compute_svd).
+  lwork = static_cast<int>(work[0] + 1);
 
   // resize workspace arrays
   work.resize(static_cast<size_type> (lwork));
@@ -899,8 +901,9 @@ LAPACKFullMatrix<number>::compute_generalized_eigenvalues_symmetric (
   // sygv returns info=0 on success. Since we only queried the optimal size
   // for work, everything else would not be acceptable.
   Assert (info == 0, ExcInternalError());
-  // Allocate working array according to suggestion.
-  lwork = boost::math::iround(work[0]);
+  // Allocate working array according to suggestion (same strategy as was
+  // noted in compute_svd).
+  lwork = static_cast<int>(work[0] + 1);
 
   // resize workspace array
   work.resize((size_type) lwork);

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.