From cca3333ef26ec25368be4be3d3b5da888488d00f Mon Sep 17 00:00:00 2001 From: Andrei Savici <saviciat@ornl.gov> Date: Wed, 5 Oct 2016 12:22:49 -0400 Subject: [PATCH] Re #17695. More nans and infs --- Framework/API/src/WorkspaceOpOverloads.cpp | 5 ++-- Framework/Algorithms/src/ConvertUnits.cpp | 2 +- .../src/ConvertUnitsUsingDetectorTable.cpp | 2 -- .../src/DetectorEfficiencyVariation.cpp | 5 +--- .../Algorithms/src/DiffractionFocussing.cpp | 3 +-- .../src/FindDetectorsOutsideLimits.cpp | 4 +-- .../Algorithms/src/GetDetectorOffsets.cpp | 2 +- .../Algorithms/src/IntegrateByComponent.cpp | 9 ++----- Framework/Algorithms/src/Qxy.cpp | 3 +-- Framework/Algorithms/src/Rebin2D.cpp | 1 - .../Algorithms/src/ReplaceSpecialValues.cpp | 5 ++-- Framework/Algorithms/src/ResampleX.cpp | 5 ++-- Framework/Algorithms/src/Stitch1D.cpp | 16 ++++-------- .../Algorithms/src/TOFSANSResolution.cpp | 4 +-- .../src/WeightedMeanOfWorkspace.cpp | 5 +--- .../Algorithms/test/AverageLogDataTest.h | 5 ++-- Framework/Algorithms/test/GetAllEiTest.h | 5 ++-- .../Algorithms/test/PDFFourierTransformTest.h | 4 +-- Framework/Algorithms/test/Q1D2Test.h | 25 +++++++++---------- Framework/Algorithms/test/Stitch1DTest.h | 11 ++++---- Framework/Algorithms/test/TransposeTest.h | 5 ++-- .../src/AugmentedLagrangianOptimizer.cpp | 4 +-- Framework/CurveFitting/src/FitMW.cpp | 6 ++--- .../src/FuncMinimizers/FABADAMinimizer.cpp | 8 +++--- .../src/Functions/BackToBackExponential.cpp | 3 +-- .../CurveFitting/src/Functions/Gaussian.cpp | 3 +-- .../src/HistogramDomainCreator.cpp | 4 +-- .../CurveFitting/src/IMWDomainCreator.cpp | 1 - .../test/Algorithms/CalculateChiSquaredTest.h | 6 ++--- Framework/DataObjects/src/EventList.cpp | 10 ++------ Framework/Kernel/test/UnitTest.h | 2 +- Framework/MDAlgorithms/src/FindPeaksMD.cpp | 4 +-- MantidPlot/src/Mantid/MantidMatrix.cpp | 2 +- MantidPlot/src/Spectrogram.cpp | 3 +-- MantidQt/API/src/SignalRange.cpp | 2 +- .../src/InstrumentView/InstrumentActor.cpp | 5 ++-- .../src/InstrumentView/RotationSurface.cpp | 8 ++---- Vates/VatesAPI/src/MetaDataExtractorUtils.cpp | 7 +++--- Vates/VatesAPI/src/vtkMDHistoHex4DFactory.cpp | 1 - Vates/VatesAPI/src/vtkPeakMarkerFactory.cpp | 1 - Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp | 1 - 41 files changed, 75 insertions(+), 132 deletions(-) diff --git a/Framework/API/src/WorkspaceOpOverloads.cpp b/Framework/API/src/WorkspaceOpOverloads.cpp index 86b49a7884f..3be1fd8b086 100644 --- a/Framework/API/src/WorkspaceOpOverloads.cpp +++ b/Framework/API/src/WorkspaceOpOverloads.cpp @@ -420,15 +420,14 @@ bool WorkspaceHelpers::commonBoundaries(const MatrixWorkspace_const_sptr WS) { const double commonSum = std::accumulate(WS->readX(0).begin(), WS->readX(0).end(), 0.); // If this results in infinity or NaN, then we can't tell - return false - if (commonSum == std::numeric_limits<double>::infinity() || - commonSum != commonSum) + if (!std::isfinite(commonSum)) return false; const size_t numHist = WS->getNumberHistograms(); for (size_t j = 1; j < numHist; ++j) { const double sum = std::accumulate(WS->readX(j).begin(), WS->readX(j).end(), 0.); // If this results in infinity or NaN, then we can't tell - return false - if (sum == std::numeric_limits<double>::infinity() || sum != sum) + if (!std::isfinite(sum)) return false; if (std::abs(commonSum) < 1.0E-7 && std::abs(sum) < 1.0E-7) { diff --git a/Framework/Algorithms/src/ConvertUnits.cpp b/Framework/Algorithms/src/ConvertUnits.cpp index ba046bf0efb..83d1698a067 100644 --- a/Framework/Algorithms/src/ConvertUnits.cpp +++ b/Framework/Algorithms/src/ConvertUnits.cpp @@ -674,7 +674,7 @@ const std::vector<double> ConvertUnits::calculateRebinParams( auto &XData = workspace->x(i); double xfront = XData.front(); double xback = XData.back(); - if (boost::math::isfinite(xfront) && boost::math::isfinite(xback)) { + if (std::isfinite(xfront) && std::isfinite(xback)) { if (xfront < XMin) XMin = xfront; if (xback > XMax) diff --git a/Framework/Algorithms/src/ConvertUnitsUsingDetectorTable.cpp b/Framework/Algorithms/src/ConvertUnitsUsingDetectorTable.cpp index 3b374881c1a..8b57d341e7e 100644 --- a/Framework/Algorithms/src/ConvertUnitsUsingDetectorTable.cpp +++ b/Framework/Algorithms/src/ConvertUnitsUsingDetectorTable.cpp @@ -12,12 +12,10 @@ #include <boost/bind.hpp> #include <boost/function.hpp> -#include <boost/math/special_functions/fpclassify.hpp> #include <algorithm> #include <numeric> #include <cfloat> -#include <limits> namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/DetectorEfficiencyVariation.cpp b/Framework/Algorithms/src/DetectorEfficiencyVariation.cpp index 5bd44d2b2e9..101c657e0bb 100644 --- a/Framework/Algorithms/src/DetectorEfficiencyVariation.cpp +++ b/Framework/Algorithms/src/DetectorEfficiencyVariation.cpp @@ -3,8 +3,6 @@ #include "MantidAPI/SpectrumInfo.h" #include "MantidKernel/BoundedValidator.h" -#include <boost/math/special_functions/fpclassify.hpp> - namespace Mantid { namespace Algorithms { @@ -236,8 +234,7 @@ int DetectorEfficiencyVariation::doDetectorTests( const double signal2 = counts2->y(i)[0]; // Mask out NaN and infinite - if (boost::math::isinf(signal1) || boost::math::isnan(signal1) || - boost::math::isinf(signal2) || boost::math::isnan(signal2)) { + if (!std::isfinite(signal1) || !std::isfinite(signal2)) { maskWS->mutableY(i)[0] = deadValue; PARALLEL_ATOMIC ++numFailed; diff --git a/Framework/Algorithms/src/DiffractionFocussing.cpp b/Framework/Algorithms/src/DiffractionFocussing.cpp index 3b5ae57b7e7..458256d04f9 100644 --- a/Framework/Algorithms/src/DiffractionFocussing.cpp +++ b/Framework/Algorithms/src/DiffractionFocussing.cpp @@ -210,8 +210,7 @@ void DiffractionFocussing::calculateRebinParams( auto &xVec = workspace->x(i); const double &localMin = xVec.front(); const double &localMax = xVec.back(); - if (localMin != std::numeric_limits<double>::infinity() && - localMax != std::numeric_limits<double>::infinity()) { + if (std::isfinite(localMin) && std::isfinite(localMax)) { min = std::min(min, localMin); max = std::max(max, localMax); } diff --git a/Framework/Algorithms/src/FindDetectorsOutsideLimits.cpp b/Framework/Algorithms/src/FindDetectorsOutsideLimits.cpp index cc9a172ec5c..e4967081d2a 100644 --- a/Framework/Algorithms/src/FindDetectorsOutsideLimits.cpp +++ b/Framework/Algorithms/src/FindDetectorsOutsideLimits.cpp @@ -5,8 +5,6 @@ #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/MultiThreaded.h" -#include <boost/math/special_functions/fpclassify.hpp> - #include <fstream> #include <cmath> @@ -145,7 +143,7 @@ void FindDetectorsOutsideLimits::exec() { const double &yValue = countsWS->y(countsInd)[0]; // Mask out NaN and infinite - if (boost::math::isinf(yValue) || boost::math::isnan(yValue)) { + if (!std::isfinite(yValue)) { keepData = false; } else { if (yValue <= lowThreshold) { diff --git a/Framework/Algorithms/src/GetDetectorOffsets.cpp b/Framework/Algorithms/src/GetDetectorOffsets.cpp index d0028db0599..3f20683ea86 100644 --- a/Framework/Algorithms/src/GetDetectorOffsets.cpp +++ b/Framework/Algorithms/src/GetDetectorOffsets.cpp @@ -178,7 +178,7 @@ double GetDetectorOffsets::fitSpectra(const int64_t s, bool isAbsolbute) { const double peakLoc = inputW->x(s)[it - yValues.begin()]; // Return if peak of Cross Correlation is nan (Happens when spectra is zero) // Pixel with large offset will be masked - if (boost::math::isnan(peakHeight)) + if (std::isnan(peakHeight)) return (1000.); IAlgorithm_sptr fit_alg; diff --git a/Framework/Algorithms/src/IntegrateByComponent.cpp b/Framework/Algorithms/src/IntegrateByComponent.cpp index f2e51448bb1..06b10990bca 100644 --- a/Framework/Algorithms/src/IntegrateByComponent.cpp +++ b/Framework/Algorithms/src/IntegrateByComponent.cpp @@ -4,7 +4,6 @@ #include "MantidGeometry/Instrument.h" #include "MantidKernel/BoundedValidator.h" -#include <boost/math/special_functions/fpclassify.hpp> #include <gsl/gsl_statistics.h> #include <unordered_map> @@ -91,9 +90,7 @@ void IntegrateByComponent::exec() { const double yValue = integratedWS->readY(hists[i])[0]; const double eValue = integratedWS->readE(hists[i])[0]; - if (boost::math::isnan(yValue) || boost::math::isinf(yValue) || - boost::math::isnan(eValue) || - boost::math::isinf(eValue)) // NaNs/Infs + if (!std::isfinite(yValue) || !std::isfinite(eValue)) // NaNs/Infs continue; // Now we have a good value @@ -128,9 +125,7 @@ void IntegrateByComponent::exec() { const double yValue = integratedWS->readY(hists[i])[0]; const double eValue = integratedWS->readE(hists[i])[0]; - if (boost::math::isnan(yValue) || boost::math::isinf(yValue) || - boost::math::isnan(eValue) || - boost::math::isinf(eValue)) // NaNs/Infs + if (!std::isfinite(yValue) || !std::isfinite(eValue)) // NaNs/Infs continue; // Now we have a good value diff --git a/Framework/Algorithms/src/Qxy.cpp b/Framework/Algorithms/src/Qxy.cpp index ae243f9f5d4..cd9a2fdcde1 100644 --- a/Framework/Algorithms/src/Qxy.cpp +++ b/Framework/Algorithms/src/Qxy.cpp @@ -13,7 +13,6 @@ #include "MantidKernel/CompositeValidator.h" #include "MantidKernel/UnitFactory.h" #include "MantidKernel/VectorHelper.h" -#include <boost/math/special_functions/fpclassify.hpp> namespace Mantid { namespace Algorithms { @@ -235,7 +234,7 @@ void Qxy::exec() { double &outputBinY = outputWorkspace->dataY(yIndex)[xIndex]; double &outputBinE = outputWorkspace->dataE(yIndex)[xIndex]; - if (boost::math::isnan(outputBinY)) { + if (std::isnan(outputBinY)) { outputBinY = outputBinE = 0; } // Add the contents of the current bin to the 2D array. diff --git a/Framework/Algorithms/src/Rebin2D.cpp b/Framework/Algorithms/src/Rebin2D.cpp index a6cf257796e..1e8edf6919f 100644 --- a/Framework/Algorithms/src/Rebin2D.cpp +++ b/Framework/Algorithms/src/Rebin2D.cpp @@ -15,7 +15,6 @@ #include "MantidKernel/PropertyWithValue.h" #include "MantidKernel/VectorHelper.h" -#include <boost/math/special_functions/fpclassify.hpp> namespace Mantid { namespace Algorithms { diff --git a/Framework/Algorithms/src/ReplaceSpecialValues.cpp b/Framework/Algorithms/src/ReplaceSpecialValues.cpp index ebce095ad18..bd36b77a277 100644 --- a/Framework/Algorithms/src/ReplaceSpecialValues.cpp +++ b/Framework/Algorithms/src/ReplaceSpecialValues.cpp @@ -3,7 +3,6 @@ //---------------------------------------------------------------------- #include "MantidAlgorithms/ReplaceSpecialValues.h" #include "MantidKernel/Exception.h" -#include "boost/math/special_functions/fpclassify.hpp" #include <limits> #include <cmath> @@ -84,11 +83,11 @@ void ReplaceSpecialValues::performUnaryOperation(const double XIn, } bool ReplaceSpecialValues::checkIfNan(const double &value) const { - return (boost::math::isnan(value)); + return (std::isnan(value)); } bool ReplaceSpecialValues::checkIfInfinite(const double &value) const { - return (std::abs(value) == std::numeric_limits<double>::infinity()); + return (std::isinf(value)); } bool ReplaceSpecialValues::checkIfBig(const double &value) const { diff --git a/Framework/Algorithms/src/ResampleX.cpp b/Framework/Algorithms/src/ResampleX.cpp index ee4c36e24e2..6e2741a75ac 100644 --- a/Framework/Algorithms/src/ResampleX.cpp +++ b/Framework/Algorithms/src/ResampleX.cpp @@ -6,7 +6,6 @@ #include "MantidKernel/BoundedValidator.h" #include "MantidKernel/VectorHelper.h" -#include <boost/math/special_functions/fpclassify.hpp> #include <sstream> @@ -135,14 +134,14 @@ string determineXMinMax(MatrixWorkspace_sptr inputWS, vector<double> &xmins, if (updateXMins || updateXMaxs) { const MantidVec &xvalues = inputWS->getSpectrum(i).dataX(); if (updateXMins) { - if (boost::math::isnan(xvalues.front())) { + if (std::isnan(xvalues.front())) { xmins.push_back(xmin_wksp); } else { xmins.push_back(xvalues.front()); } } if (updateXMaxs) { - if (boost::math::isnan(xvalues.back())) { + if (std::isnan(xvalues.back())) { xmaxs.push_back(xmax_wksp); } else { xmaxs.push_back(xvalues.back()); diff --git a/Framework/Algorithms/src/Stitch1D.cpp b/Framework/Algorithms/src/Stitch1D.cpp index 26e770d3557..55226f5a4a7 100644 --- a/Framework/Algorithms/src/Stitch1D.cpp +++ b/Framework/Algorithms/src/Stitch1D.cpp @@ -30,12 +30,6 @@ MinMaxTuple calculateXIntersection(MatrixWorkspace_sptr lhsWS, } bool isNonzero(double i) { return (0 != i); } - -bool isNan(const double &value) { return boost::math::isnan(value); } - -bool isInf(const double &value) { - return std::abs(value) == std::numeric_limits<double>::infinity(); -} } namespace Mantid { @@ -318,18 +312,18 @@ MatrixWorkspace_sptr Stitch1D::rebin(MatrixWorkspace_sptr &input, for (size_t j = 0; j < sourceY.size(); ++j) { const double &value = sourceY[j]; const double &eValue = sourceE[j]; - if (isNan(value)) { + if (std::isnan(value)) { nanYIndexes.push_back(j); sourceY[j] = 0; - } else if (isInf(value)) { + } else if (std::isinf(value)) { infYIndexes.push_back(j); sourceY[j] = 0; } - if (isNan(eValue)) { + if (std::isnan(eValue)) { nanEIndexes.push_back(j); sourceE[j] = 0; - } else if (isInf(eValue)) { + } else if (std::isinf(eValue)) { infEIndexes.push_back(j); sourceE[j] = 0; } @@ -580,7 +574,7 @@ void Stitch1D::exec() { scaleFactor = ratio->readY(0).front(); errorScaleFactor = ratio->readE(0).front(); if (scaleFactor < 1e-2 || scaleFactor > 1e2 || - boost::math::isnan(scaleFactor)) { + std::isnan(scaleFactor)) { std::stringstream messageBuffer; messageBuffer << "Stitch1D calculated scale factor is: " << scaleFactor << ". Check that in both input workspaces the integrated " diff --git a/Framework/Algorithms/src/TOFSANSResolution.cpp b/Framework/Algorithms/src/TOFSANSResolution.cpp index dc8684db226..92de9e1f33d 100644 --- a/Framework/Algorithms/src/TOFSANSResolution.cpp +++ b/Framework/Algorithms/src/TOFSANSResolution.cpp @@ -12,8 +12,6 @@ #include "MantidKernel/RebinParamsValidator.h" #include "MantidKernel/VectorHelper.h" -#include "boost/math/special_functions/fpclassify.hpp" - namespace Mantid { namespace Algorithms { @@ -203,7 +201,7 @@ void TOFSANSResolution::exec() { // By using only events with a positive weight, we use only the data // distribution and leave out the background events. // Note: we are looping over bins, therefore the xLength-1. - if (iq >= 0 && iq < xLength - 1 && !boost::math::isnan(dq_over_q) && + if (iq >= 0 && iq < xLength - 1 && !std::isnan(dq_over_q) && dq_over_q > 0 && YIn[j] > 0) { _dx[iq] += q * dq_over_q * YIn[j]; _norm[iq] += YIn[j]; diff --git a/Framework/Algorithms/src/WeightedMeanOfWorkspace.cpp b/Framework/Algorithms/src/WeightedMeanOfWorkspace.cpp index ce733e1af69..11fbcab1b4a 100644 --- a/Framework/Algorithms/src/WeightedMeanOfWorkspace.cpp +++ b/Framework/Algorithms/src/WeightedMeanOfWorkspace.cpp @@ -4,8 +4,6 @@ #include "MantidDataObjects/EventWorkspace.h" #include "MantidGeometry/Instrument.h" -#include <boost/math/special_functions/fpclassify.hpp> - namespace Mantid { using namespace API; using namespace DataObjects; @@ -67,8 +65,7 @@ void WeightedMeanOfWorkspace::exec() { MantidVec e = inputWS->dataE(i); double weight = 0.0; for (std::size_t j = 0; j < y.size(); ++j) { - if (!boost::math::isnan(y[j]) && !boost::math::isinf(y[j]) && - !boost::math::isnan(e[j]) && !boost::math::isinf(e[j])) { + if (std::isfinite(y[j]) && std::isfinite(e[j])) { weight = 1.0 / (e[j] * e[j]); averageValue += (y[j] * weight); weightSum += weight; diff --git a/Framework/Algorithms/test/AverageLogDataTest.h b/Framework/Algorithms/test/AverageLogDataTest.h index 9586a085fda..0323e175ef1 100644 --- a/Framework/Algorithms/test/AverageLogDataTest.h +++ b/Framework/Algorithms/test/AverageLogDataTest.h @@ -6,7 +6,6 @@ #include "MantidAlgorithms/AverageLogData.h" #include "MantidKernel/TimeSeriesProperty.h" #include "MantidTestHelpers/WorkspaceCreationHelper.h" -#include <boost/math/special_functions/fpclassify.hpp> using Mantid::Algorithms::AverageLogData; @@ -102,8 +101,8 @@ public: // check average const double av = alg.getProperty("Average"), err = alg.getProperty("Error"); - TS_ASSERT(boost::math::isnan(av)); - TS_ASSERT(boost::math::isnan(err)); + TS_ASSERT(std::isnan(av)); + TS_ASSERT(std::isnan(err)); // Remove workspace from the data service.*/ Mantid::API::AnalysisDataService::Instance().remove(inputWS); diff --git a/Framework/Algorithms/test/GetAllEiTest.h b/Framework/Algorithms/test/GetAllEiTest.h index ef27ed4a6b1..2365239cc9f 100644 --- a/Framework/Algorithms/test/GetAllEiTest.h +++ b/Framework/Algorithms/test/GetAllEiTest.h @@ -2,7 +2,6 @@ #define GETALLEI_TEST_H_ #include <memory> -#include <boost/math/special_functions/fpclassify.hpp> #include <cxxtest/TestSuite.h> #include "MantidAlgorithms/GetAllEi.h" #include "MantidGeometry/Instrument.h" @@ -443,8 +442,8 @@ public: auto Xsp2 = wws->getSpectrum(1).mutableX(); size_t nSpectra = Xsp2.size(); TS_ASSERT_EQUALS(nSpectra, 101); - TS_ASSERT(boost::math::isinf(Xsp1[nSpectra - 1])); - TS_ASSERT(boost::math::isinf(Xsp2[nSpectra - 1])); + TS_ASSERT(std::isinf(Xsp1[nSpectra - 1])); + TS_ASSERT(std::isinf(Xsp2[nSpectra - 1])); // for(size_t i=0;i<Xsp1.size();i++){ // TS_ASSERT_DELTA(Xsp1[i],Xsp2[i],1.e-6); diff --git a/Framework/Algorithms/test/PDFFourierTransformTest.h b/Framework/Algorithms/test/PDFFourierTransformTest.h index 6d37b7188c7..3e5de969f91 100644 --- a/Framework/Algorithms/test/PDFFourierTransformTest.h +++ b/Framework/Algorithms/test/PDFFourierTransformTest.h @@ -1,9 +1,9 @@ #ifndef MANTID_ALGORITHMS_PDFFOURIERTRANSFORMTEST_H_ #define MANTID_ALGORITHMS_PDFFOURIERTRANSFORMTEST_H_ -#include <boost/math/special_functions/fpclassify.hpp> #include <cxxtest/TestSuite.h> #include <numeric> +#include <cmath> #include "MantidKernel/Timer.h" #include "MantidKernel/System.h" #include "MantidKernel/UnitFactory.h" @@ -116,7 +116,7 @@ public: TS_ASSERT_DELTA(R[249], 2.5, 0.0001); // make sure that nan didn' slip in TS_ASSERT(std::find_if(GofR.begin(), GofR.end(), - boost::math::isnan<double>) == GofR.end()); + static_cast<bool (*)(double)>(std::isnan)) == GofR.end()); } void test_filter() { diff --git a/Framework/Algorithms/test/Q1D2Test.h b/Framework/Algorithms/test/Q1D2Test.h index fe2f2bad20c..dfdadc23a7d 100644 --- a/Framework/Algorithms/test/Q1D2Test.h +++ b/Framework/Algorithms/test/Q1D2Test.h @@ -10,7 +10,6 @@ #include "MantidDataHandling/LoadRaw3.h" #include "MantidDataHandling/LoadRKH.h" #include "MantidDataHandling/MaskDetectors.h" -#include <boost/math/special_functions/fpclassify.hpp> #include "MantidTestHelpers/WorkspaceCreationHelper.h" @@ -93,12 +92,12 @@ public: // empty bins are 0/0 TS_ASSERT_DELTA(result->readY(0).front(), 2226533, 1) TS_ASSERT_DELTA(result->readY(0)[4], 946570.8, 0.1) - TS_ASSERT(boost::math::isnan(result->readY(0)[18])) - TS_ASSERT(boost::math::isnan(result->readY(0).back())) + TS_ASSERT(std::isnan(result->readY(0)[18])) + TS_ASSERT(std::isnan(result->readY(0).back())) TS_ASSERT_DELTA(result->readE(0)[1], 57964.04, 0.01) TS_ASSERT_DELTA(result->readE(0)[5], 166712.6, 0.1) - TS_ASSERT(boost::math::isnan(result->readE(0).back())) + TS_ASSERT(std::isnan(result->readE(0).back())) Mantid::API::AnalysisDataService::Instance().remove(outputWS); } @@ -196,12 +195,12 @@ public: TS_ASSERT_DELTA(result->readY(0).front(), 944237.8, 0.1) TS_ASSERT_DELTA(result->readY(0)[3], 1009296, 1) TS_ASSERT_DELTA(result->readY(0)[12], 620952.6, 0.1) - TS_ASSERT(boost::math::isnan(result->readY(0).back())) + TS_ASSERT(std::isnan(result->readY(0).back())) // empty bins are 0/0 TS_ASSERT_DELTA(result->readE(0)[2], 404981, 10) TS_ASSERT_DELTA(result->readE(0)[10], 489710.39, 100) - TS_ASSERT(boost::math::isnan(result->readE(0)[7])) + TS_ASSERT(std::isnan(result->readE(0)[7])) TSM_ASSERT("Should not have a DX value", !result->hasDx(0)) } @@ -276,11 +275,11 @@ public: TS_ASSERT_DELTA(gravity->readY(0)[3], 1009296.4, 0.8) TS_ASSERT_DELTA(gravity->readY(0)[10], 891346.9, 0.1) - TS_ASSERT(boost::math::isnan(gravity->readY(0)[78])) + TS_ASSERT(std::isnan(gravity->readY(0)[78])) TS_ASSERT_DELTA(gravity->readE(0).front(), 329383, 1) TS_ASSERT_DELTA(gravity->readE(0)[10], 489708, 1) // 489710 - TS_ASSERT(boost::math::isnan(gravity->readE(0)[77])) + TS_ASSERT(std::isnan(gravity->readE(0)[77])) Mantid::API::AnalysisDataService::Instance().remove(outputWS); } @@ -315,13 +314,13 @@ public: TS_ASSERT_EQUALS(result->readX(0).back(), 0.5) TS_ASSERT_DELTA(result->readY(0).front(), 1192471.95, 0.1) - TS_ASSERT(boost::math::isnan(result->readY(0)[3])) + TS_ASSERT(std::isnan(result->readY(0)[3])) TS_ASSERT_DELTA(result->readY(0)[12], 503242.79, 0.1) - TS_ASSERT(boost::math::isnan(result->readY(0).back())) + TS_ASSERT(std::isnan(result->readY(0).back())) TS_ASSERT_DELTA(result->readE(0)[2], 404980, 1) TS_ASSERT_DELTA(result->readE(0)[10], 489708, 100) - TS_ASSERT(boost::math::isnan(result->readE(0)[7])) + TS_ASSERT(std::isnan(result->readE(0)[7])) } // here the cut parameters are set but should only affect detectors with lower @@ -356,8 +355,8 @@ public: for (size_t i = 0; i < nocuts->readY(0).size(); ++i) { TS_ASSERT_EQUALS(nocuts->readX(0)[i], noGrav->readX(0)[i]) - if (!boost::math::isnan(nocuts->readY(0)[i]) && - !boost::math::isnan(nocuts->readE(0)[i])) { + if (!std::isnan(nocuts->readY(0)[i]) && + !std::isnan(nocuts->readE(0)[i])) { TS_ASSERT_EQUALS(nocuts->readY(0)[i], noGrav->readY(0)[i]) TS_ASSERT_EQUALS(nocuts->readE(0)[i], noGrav->readE(0)[i]) diff --git a/Framework/Algorithms/test/Stitch1DTest.h b/Framework/Algorithms/test/Stitch1DTest.h index ea1d73ebc81..d1094836d2e 100644 --- a/Framework/Algorithms/test/Stitch1DTest.h +++ b/Framework/Algorithms/test/Stitch1DTest.h @@ -11,7 +11,6 @@ #include <algorithm> #include <math.h> #include <boost/tuple/tuple.hpp> -#include <boost/math/special_functions.hpp> #include <boost/make_shared.hpp> using namespace Mantid::API; @@ -628,7 +627,7 @@ public: double scaleFactor = ret.get<1>(); TSM_ASSERT("ScaleFactor should not be NAN", - !boost::math::isnan(scaleFactor)); + !std::isnan(scaleFactor)); } void test_patch_inf_y_value_for_scaling() { @@ -658,7 +657,7 @@ public: double scaleFactor = ret.get<1>(); TSM_ASSERT("ScaleFactor should not be Infinity", - !boost::math::isinf(scaleFactor)); + !std::isinf(scaleFactor)); } void test_reset_nans() { @@ -674,7 +673,7 @@ public: auto e = MantidVec(nspectrum * (x.size() - 1), 1); double nan = std::numeric_limits<double>::quiet_NaN(); - y[0] = nan; // Add a Infinity + y[0] = nan; // Add a nan MatrixWorkspace_sptr lhsWS = createWorkspace(x, y, e, static_cast<int>(nspectrum)); @@ -689,10 +688,10 @@ public: double scaleFactor = ret.get<1>(); TSM_ASSERT("ScaleFactor should not be Infinity", - !boost::math::isinf(scaleFactor)); + !std::isinf(scaleFactor)); auto outY = outWs->readY(0); - TSM_ASSERT("Nans should be put back", boost::math::isnan(outY[0])); + TSM_ASSERT("Nans should be put back", std::isnan(outY[0])); } }; diff --git a/Framework/Algorithms/test/TransposeTest.h b/Framework/Algorithms/test/TransposeTest.h index 966c40d44c6..664f820e6e8 100644 --- a/Framework/Algorithms/test/TransposeTest.h +++ b/Framework/Algorithms/test/TransposeTest.h @@ -2,7 +2,6 @@ #define TRANSPOSETEST_H_ #include <cxxtest/TestSuite.h> -#include <boost/math/special_functions/fpclassify.hpp> #include "MantidTestHelpers/WorkspaceCreationHelper.h" @@ -121,8 +120,8 @@ public: TS_ASSERT_EQUALS(outputWS->dataF(0).size(), 4); TS_ASSERT_EQUALS(outputWS->dataF(3)[1], inputWS->dataF(1)[3]); // Check a nan - bool inNan = boost::math::isnan(inputWS->dataY(0)[5]); - bool outNan = boost::math::isnan(outputWS->dataY(5)[0]); + bool inNan = std::isnan(inputWS->dataY(0)[5]); + bool outNan = std::isnan(outputWS->dataY(5)[0]); TS_ASSERT_EQUALS(outNan, inNan); delete transpose; diff --git a/Framework/CurveFitting/src/AugmentedLagrangianOptimizer.cpp b/Framework/CurveFitting/src/AugmentedLagrangianOptimizer.cpp index b4c421b85f2..93e1d0d7df9 100644 --- a/Framework/CurveFitting/src/AugmentedLagrangianOptimizer.cpp +++ b/Framework/CurveFitting/src/AugmentedLagrangianOptimizer.cpp @@ -2,7 +2,7 @@ #include "MantidKernel/Exception.h" #include <boost/make_shared.hpp> -#include <boost/math/special_functions/fpclassify.hpp> +#include <cmath> #include <gsl/gsl_multimin.h> @@ -109,7 +109,7 @@ int relstopX(const std::vector<double> &xvOld, const std::vector<double> &xvNew, int relstopX(const std::vector<double> &xvOld, const gsl_vector *xvNew, double reltol, double abstol) { for (size_t i = 0; i < xvOld.size(); ++i) { - if (boost::math::isnan(gsl_vector_get(xvNew, i))) + if (std::isnan(gsl_vector_get(xvNew, i))) return 1; if (!relstop(xvOld[i], gsl_vector_get(xvNew, i), reltol, abstol)) return 0; diff --git a/Framework/CurveFitting/src/FitMW.cpp b/Framework/CurveFitting/src/FitMW.cpp index cdd87d5d441..2fc16c200b3 100644 --- a/Framework/CurveFitting/src/FitMW.cpp +++ b/Framework/CurveFitting/src/FitMW.cpp @@ -20,7 +20,7 @@ #include "MantidKernel/EmptyValues.h" #include "MantidKernel/Matrix.h" -#include <boost/math/special_functions/fpclassify.hpp> +#include <cmath> #include <algorithm> namespace Mantid { @@ -183,12 +183,12 @@ void FitMW::createDomain(boost::shared_ptr<API::FunctionDomain> &domain, error /= binWidth; } - if (!boost::math::isfinite(y)) // nan or inf data + if (!std::isfinite(y)) // nan or inf data { if (!m_ignoreInvalidData) throw std::runtime_error("Infinte number or NaN found in input data."); y = 0.0; // leaving inf or nan would break the fit - } else if (!boost::math::isfinite(error)) // nan or inf error + } else if (!std::isfinite(error)) // nan or inf error { if (!m_ignoreInvalidData) throw std::runtime_error("Infinte number or NaN found in input data."); diff --git a/Framework/CurveFitting/src/FuncMinimizers/FABADAMinimizer.cpp b/Framework/CurveFitting/src/FuncMinimizers/FABADAMinimizer.cpp index a3e24888f6f..d6eb20dcda7 100644 --- a/Framework/CurveFitting/src/FuncMinimizers/FABADAMinimizer.cpp +++ b/Framework/CurveFitting/src/FuncMinimizers/FABADAMinimizer.cpp @@ -26,7 +26,7 @@ #include <boost/random/variate_generator.hpp> #include <boost/random/mersenne_twister.hpp> #include <boost/version.hpp> -#include <boost/math/special_functions/fpclassify.hpp> +#include <cmath> namespace Mantid { namespace CurveFitting { @@ -338,7 +338,7 @@ bool FABADAMinimizer::iterate(size_t) { // the user should be aware of that. // Set the new value in order to calculate the new Chi square value - if (boost::math::isnan(new_value)) { + if (std::isnan(new_value)) { throw std::runtime_error("Parameter value is NaN."); } new_parameters.set(i, new_value); @@ -773,7 +773,7 @@ void FABADAMinimizer::TieApplication(const size_t &ParameterIndex, API::ParameterTie *tie = m_FitFunction->getTie(j); if (tie) { new_value = tie->eval(); - if (boost::math::isnan(new_value)) { // maybe not needed + if (std::isnan(new_value)) { // maybe not needed throw std::runtime_error("Parameter value is NaN."); } new_parameters.set(j, new_value); @@ -785,7 +785,7 @@ void FABADAMinimizer::TieApplication(const size_t &ParameterIndex, API::ParameterTie *tie = m_FitFunction->getTie(i); if (tie) { new_value = tie->eval(); - if (boost::math::isnan(new_value)) { // maybe not needed + if (std::isnan(new_value)) { // maybe not needed throw std::runtime_error("Parameter value is NaN."); } new_parameters.set(i, new_value); diff --git a/Framework/CurveFitting/src/Functions/BackToBackExponential.cpp b/Framework/CurveFitting/src/Functions/BackToBackExponential.cpp index 64a5d5aae6a..ab588d2eb0e 100644 --- a/Framework/CurveFitting/src/Functions/BackToBackExponential.cpp +++ b/Framework/CurveFitting/src/Functions/BackToBackExponential.cpp @@ -6,7 +6,6 @@ #include <gsl/gsl_sf_erf.h> #include <gsl/gsl_multifit_nlin.h> -#include <boost/math/special_functions/fpclassify.hpp> #include <cmath> #include <limits> @@ -64,7 +63,7 @@ void BackToBackExponential::setHeight(const double h) { if (area <= 0.0) { area = 1e-6; } - if (boost::math::isnan(area) || boost::math::isinf(area)) { + if (!std::isfinite(area)) { area = std::numeric_limits<double>::max() / 2; } setParameter(0, area); diff --git a/Framework/CurveFitting/src/Functions/Gaussian.cpp b/Framework/CurveFitting/src/Functions/Gaussian.cpp index 9a90822fdb3..e4e7060c076 100644 --- a/Framework/CurveFitting/src/Functions/Gaussian.cpp +++ b/Framework/CurveFitting/src/Functions/Gaussian.cpp @@ -3,7 +3,6 @@ //---------------------------------------------------------------------- #include "MantidCurveFitting/Functions/Gaussian.h" #include "MantidAPI/FunctionFactory.h" -#include <boost/math/special_functions/fpclassify.hpp> #include <cmath> #include <numeric> @@ -83,7 +82,7 @@ double Gaussian::intensity() const { auto sigma = getParameter("Sigma"); if (sigma == 0.0) { auto height = getParameter("Height"); - if (boost::math::isfinite(height)) { + if (std::isfinite(height)) { m_intensityCache = height; } } else { diff --git a/Framework/CurveFitting/src/HistogramDomainCreator.cpp b/Framework/CurveFitting/src/HistogramDomainCreator.cpp index 59f68c4fae4..4eee8eb2ec5 100644 --- a/Framework/CurveFitting/src/HistogramDomainCreator.cpp +++ b/Framework/CurveFitting/src/HistogramDomainCreator.cpp @@ -84,12 +84,12 @@ void HistogramDomainCreator::createDomain( error *= dx; } - if (!boost::math::isfinite(y)) // nan or inf data + if (!std::isfinite(y)) // nan or inf data { if (!m_ignoreInvalidData) throw std::runtime_error("Infinte number or NaN found in input data."); y = 0.0; // leaving inf or nan would break the fit - } else if (!boost::math::isfinite(error)) // nan or inf error + } else if (!std::isfinite(error)) // nan or inf error { if (!m_ignoreInvalidData) throw std::runtime_error("Infinte number or NaN found in input data."); diff --git a/Framework/CurveFitting/src/IMWDomainCreator.cpp b/Framework/CurveFitting/src/IMWDomainCreator.cpp index e7004fa4f82..9a5ee6bfe89 100644 --- a/Framework/CurveFitting/src/IMWDomainCreator.cpp +++ b/Framework/CurveFitting/src/IMWDomainCreator.cpp @@ -20,7 +20,6 @@ #include "MantidKernel/EmptyValues.h" #include "MantidKernel/Matrix.h" -#include <boost/math/special_functions/fpclassify.hpp> #include <algorithm> namespace Mantid { diff --git a/Framework/CurveFitting/test/Algorithms/CalculateChiSquaredTest.h b/Framework/CurveFitting/test/Algorithms/CalculateChiSquaredTest.h index d1abcf80c08..718c447c1ee 100644 --- a/Framework/CurveFitting/test/Algorithms/CalculateChiSquaredTest.h +++ b/Framework/CurveFitting/test/Algorithms/CalculateChiSquaredTest.h @@ -14,8 +14,7 @@ #include "MantidAPI/WorkspaceFactory.h" #include "MantidKernel/EmptyValues.h" -#include <boost/math/special_functions/fpclassify.hpp> - +#include <cmath> #include <algorithm> #include <limits> @@ -310,8 +309,7 @@ private: bool isGoodValue(double y, double e) { return !ignoreInvalidData || - (!boost::math::isnan(y) && !boost::math::isinf(y) && - !boost::math::isnan(e) && !boost::math::isinf(e) && e > 0); + (std::isfinite(y) && std::isfinite(e) && e > 0); } public: diff --git a/Framework/DataObjects/src/EventList.cpp b/Framework/DataObjects/src/EventList.cpp index 7f86e40871b..c72612926d7 100644 --- a/Framework/DataObjects/src/EventList.cpp +++ b/Framework/DataObjects/src/EventList.cpp @@ -198,10 +198,6 @@ void EventList::createFromHistogram(const ISpectrum *inSpec, bool GenerateZeros, // Fresh start this->clear(true); - // Cached values for later checks - double inf = std::numeric_limits<double>::infinity(); - double ninf = -inf; - // Get the input histogram const MantidVec &X = inSpec->readX(); const MantidVec &Y = inSpec->readY(); @@ -219,12 +215,10 @@ void EventList::createFromHistogram(const ISpectrum *inSpec, bool GenerateZeros, for (size_t i = 0; i < X.size() - 1; i++) { double weight = Y[i]; - if ((weight != 0.0 || GenerateZeros) && (weight == weight) /*NAN check*/ - && (weight != inf) && (weight != ninf)) { + if ((weight != 0.0 || GenerateZeros) && std::isfinite(weight)) { double error = E[i]; // Also check that the error is not a bad number - if ((error == error) /*NAN check*/ - && (error != inf) && (error != ninf)) { + if (std::isfinite(error)) { if (GenerateMultipleEvents) { // --------- Multiple events per bin ---------- double errorSquared = error * error; diff --git a/Framework/Kernel/test/UnitTest.h b/Framework/Kernel/test/UnitTest.h index 6fb918270c2..bb5070d8f73 100644 --- a/Framework/Kernel/test/UnitTest.h +++ b/Framework/Kernel/test/UnitTest.h @@ -63,7 +63,7 @@ std::string convert_units_check_range(const Unit &aUnit, const size_t nSteps(100); double step = (range.second - range.first) / nSteps; - if (step == std::numeric_limits<double>::infinity()) { + if (std::isinf(step)) { step = (DBL_MAX / nSteps) * 2; } diff --git a/Framework/MDAlgorithms/src/FindPeaksMD.cpp b/Framework/MDAlgorithms/src/FindPeaksMD.cpp index afb3da2d5e2..974554a5cef 100644 --- a/Framework/MDAlgorithms/src/FindPeaksMD.cpp +++ b/Framework/MDAlgorithms/src/FindPeaksMD.cpp @@ -465,9 +465,7 @@ void FindPeaksMD::findPeaksHisto( double thresholdDensity = (totalSignal * ws->getInverseVolume() / double(numBoxes)) * DensityThresholdFactor * m_densityScaleFactor; - if ((thresholdDensity != thresholdDensity) || - (thresholdDensity == std::numeric_limits<double>::infinity()) || - (thresholdDensity == -std::numeric_limits<double>::infinity())) { + if (!std::isfinite(thresholdDensity)) { g_log.warning() << "Infinite or NaN overall density found. Your input data " "may be invalid. Using a 0 threshold instead.\n"; diff --git a/MantidPlot/src/Mantid/MantidMatrix.cpp b/MantidPlot/src/Mantid/MantidMatrix.cpp index 88a7dc65cbe..0899f9cc2c4 100644 --- a/MantidPlot/src/Mantid/MantidMatrix.cpp +++ b/MantidPlot/src/Mantid/MantidMatrix.cpp @@ -1146,7 +1146,7 @@ void findYRange(MatrixWorkspace_const_sptr ws, double &miny, double &maxy) { for (size_t i = 0; i < Y.size(); i++) { double aux = Y[i]; - if (fabs(aux) == std::numeric_limits<double>::infinity() || aux != aux) + if (!std::isfinite(aux)) continue; if (aux < local_min) local_min = aux; diff --git a/MantidPlot/src/Spectrogram.cpp b/MantidPlot/src/Spectrogram.cpp index 7ede4fac0a8..8d092ad7a41 100644 --- a/MantidPlot/src/Spectrogram.cpp +++ b/MantidPlot/src/Spectrogram.cpp @@ -969,8 +969,7 @@ QImage Spectrogram::renderImage(const QwtScaleMap &xMap, double xmin, xmax; mantidFun->getRowXRange(row, xmin, xmax); int jmin = -1; - if (xmin != std::numeric_limits<double>::infinity() && xmin == xmin && - xmax != std::numeric_limits<double>::infinity() && xmax == xmax) { + if (std::isfinite(xmin) && std::isfinite(xmax)) { jmin = xMap.transform(xmin) - rect.left(); } else { continue; diff --git a/MantidQt/API/src/SignalRange.cpp b/MantidQt/API/src/SignalRange.cpp index d98440bc8de..ae2ef0cb663 100644 --- a/MantidQt/API/src/SignalRange.cpp +++ b/MantidQt/API/src/SignalRange.cpp @@ -131,7 +131,7 @@ QwtDoubleInterval SignalRange::getRange(Mantid::API::IMDIterator *it) { do { double signal = it->getNormalizedSignal(); // Skip any 'infs' as it screws up the color scale - if (signal != inf) { + if (!std::isinf(signal)) { if (signal < minSignal) minSignal = signal; if (signal > maxSignal) diff --git a/MantidQt/MantidWidgets/src/InstrumentView/InstrumentActor.cpp b/MantidQt/MantidWidgets/src/InstrumentView/InstrumentActor.cpp index fa99f1cb461..5341ec549a1 100644 --- a/MantidQt/MantidWidgets/src/InstrumentView/InstrumentActor.cpp +++ b/MantidQt/MantidWidgets/src/InstrumentView/InstrumentActor.cpp @@ -134,8 +134,7 @@ void InstrumentActor::setUpWorkspace( for (size_t i = 0; i < nHist; ++i) { const Mantid::MantidVec &values = sharedWorkspace->readX(i); double xtest = values.front(); - if (xtest != std::numeric_limits<double>::infinity()) { - + if (!std::isinf(xtest)) { if (xtest < m_WkspBinMinValue) { m_WkspBinMinValue = xtest; } else if (xtest > m_WkspBinMaxValue) { @@ -145,7 +144,7 @@ void InstrumentActor::setUpWorkspace( } xtest = values.back(); - if (xtest != std::numeric_limits<double>::infinity()) { + if (!std::isinf(xtest)) { if (xtest < m_WkspBinMinValue) { m_WkspBinMinValue = xtest; } else if (xtest > m_WkspBinMaxValue) { diff --git a/MantidQt/MantidWidgets/src/InstrumentView/RotationSurface.cpp b/MantidQt/MantidWidgets/src/InstrumentView/RotationSurface.cpp index 35246093906..355776936ad 100644 --- a/MantidQt/MantidWidgets/src/InstrumentView/RotationSurface.cpp +++ b/MantidQt/MantidWidgets/src/InstrumentView/RotationSurface.cpp @@ -160,17 +160,13 @@ void RotationSurface::init() { double dV = fabs(m_v_max - m_v_min); double du = dU * 0.05; double dv = dV * 0.05; - if (m_width_max > du && - m_width_max != - std::numeric_limits<double>::infinity()) { + if (m_width_max > du && std::isfinite(m_width_max)) { if (du > 0 && !(dU >= m_width_max)) { m_width_max = dU; } du = m_width_max; } - if (m_height_max > dv && - m_height_max != - std::numeric_limits<double>::infinity()) { + if (m_height_max > dv && std::isfinite( m_height_max)) { if (dv > 0 && !(dV >= m_height_max)) { m_height_max = dV; } diff --git a/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp b/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp index c82485a2a3d..5d520a30563 100644 --- a/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp +++ b/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp @@ -96,17 +96,16 @@ MetaDataExtractorUtils::getMinAndMax(Mantid::API::IMDWorkspace_sptr workspace) { double minSignal = DBL_MAX; double maxSignal = -DBL_MAX; - auto inf = std::numeric_limits<double>::infinity(); for (size_t i = 0; i < iterators.size(); i++) { delete iterators[i]; double signal; signal = intervals[i].minValue(); - if (signal != inf && signal < minSignal) + if (!std::isinf(signal) && signal < minSignal) minSignal = signal; signal = intervals[i].maxValue(); - if (signal != inf && signal > maxSignal) + if (!std::isinf(signal) && signal > maxSignal) maxSignal = signal; } @@ -157,7 +156,7 @@ MetaDataExtractorUtils::getRange(Mantid::API::IMDIterator *it) { double signal = it->getNormalizedSignal(); // Skip any 'infs' as it screws up the color scale - if (signal != inf) { + if (!std::isinf(signal)) { if (signal == 0.0) minSignalZeroCheck = signal; if (signal < minSignal && signal > 0.0) diff --git a/Vates/VatesAPI/src/vtkMDHistoHex4DFactory.cpp b/Vates/VatesAPI/src/vtkMDHistoHex4DFactory.cpp index 49b10fd7cc5..5851197f8ba 100644 --- a/Vates/VatesAPI/src/vtkMDHistoHex4DFactory.cpp +++ b/Vates/VatesAPI/src/vtkMDHistoHex4DFactory.cpp @@ -5,7 +5,6 @@ #include "MantidVatesAPI/TimeToTimeStep.h" #include "MantidVatesAPI/vtkMDHistoHex4DFactory.h" #include "MantidVatesAPI/ProgressAction.h" -#include <boost/math/special_functions/fpclassify.hpp> using Mantid::API::IMDWorkspace; using Mantid::Kernel::CPUTimer; diff --git a/Vates/VatesAPI/src/vtkPeakMarkerFactory.cpp b/Vates/VatesAPI/src/vtkPeakMarkerFactory.cpp index 3003756dacf..3cb9226b654 100644 --- a/Vates/VatesAPI/src/vtkPeakMarkerFactory.cpp +++ b/Vates/VatesAPI/src/vtkPeakMarkerFactory.cpp @@ -1,6 +1,5 @@ #include "MantidVatesAPI/vtkPeakMarkerFactory.h" #include "MantidVatesAPI/ProgressAction.h" -#include <boost/math/special_functions/fpclassify.hpp> #include "MantidAPI/Workspace.h" #include "MantidAPI/IPeaksWorkspace.h" #include "MantidGeometry/Crystal/PeakShape.h" diff --git a/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp b/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp index 8c0e86e681f..8a92822e55f 100644 --- a/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp +++ b/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp @@ -30,7 +30,6 @@ #include <vtkVertex.h> #include <algorithm> -#include <boost/math/special_functions/fpclassify.hpp> #include <iterator> #include <qwt_double_interval.h> -- GitLab