diff --git a/Framework/CurveFitting/CMakeLists.txt b/Framework/CurveFitting/CMakeLists.txt index 1e059c5e3045..7ce3db4527ce 100644 --- a/Framework/CurveFitting/CMakeLists.txt +++ b/Framework/CurveFitting/CMakeLists.txt @@ -41,6 +41,7 @@ set(SRC_FILES src/FitMW.cpp src/EigenComplexMatrix.cpp src/EigenComplexVector.cpp + src/EigenFunctions.cpp src/EigenMatrix.cpp src/EigenMatrixView.cpp src/EigenVector.cpp @@ -347,6 +348,7 @@ set(INC_FILES inc/MantidCurveFitting/Functions/VesuvioResolution.h inc/MantidCurveFitting/Functions/Voigt.h inc/MantidCurveFitting/Functions/ConvTempCorrection.h + inc/MantidCurveFitting/EigenFunctions.h inc/MantidCurveFitting/GSLFunctions.h inc/MantidCurveFitting/GeneralDomainCreator.h inc/MantidCurveFitting/HalfComplex.h @@ -409,9 +411,9 @@ set(TEST_FILES EigenComplexVectorTest.h EigenFortranMatrixTest.h EigenFortranVectorTest.h + EigenFunctionsTest.h EigenJacobianTest.h EigenMatrixTest.h - EigenToGSLTest.h EigenVectorTest.h EigenViewTest.h FitMWTest.h diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/EigenFunctions.h b/Framework/CurveFitting/inc/MantidCurveFitting/EigenFunctions.h new file mode 100644 index 000000000000..3f4a57a05cd1 --- /dev/null +++ b/Framework/CurveFitting/inc/MantidCurveFitting/EigenFunctions.h @@ -0,0 +1,15 @@ +// Mantid Repository : https://github.com/mantidproject/mantid +// +// Copyright © 2026 ISIS Rutherford Appleton Laboratory UKRI, +// NScD Oak Ridge National Laboratory, European Spallation Source, +// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS +// SPDX - License - Identifier: GPL - 3.0 + +#pragma once + +#include "MantidCurveFitting/EigenMatrix.h" + +namespace Mantid::CurveFitting { + +MANTID_CURVEFITTING_DLL Eigen::MatrixXd covar_from_jacobian(const map_type &J, double epsrel); + +} // namespace Mantid::CurveFitting diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/GSLFunctions.h b/Framework/CurveFitting/inc/MantidCurveFitting/GSLFunctions.h index 49293b50af37..be62e4be5830 100644 --- a/Framework/CurveFitting/inc/MantidCurveFitting/GSLFunctions.h +++ b/Framework/CurveFitting/inc/MantidCurveFitting/GSLFunctions.h @@ -50,19 +50,5 @@ int gsl_f(const gsl_vector *x, void *params, gsl_vector *f); int gsl_df(const gsl_vector *x, void *params, gsl_matrix *J); int gsl_fdf(const gsl_vector *x, void *params, gsl_vector *f, gsl_matrix *J); -/// take data from Eigen Vector and take a gsl view -inline gsl_vector_view getGSLVectorView(vec_map_type &v) { return gsl_vector_view_array(v.data(), v.size()); } -/// take data from an Eigen Matrix and return a transposed a gsl view. -inline gsl_matrix_view getGSLMatrixView(map_type &tr) { return gsl_matrix_view_array(tr.data(), tr.cols(), tr.rows()); } - -/// take const data from Eigen Vector and take a gsl view -inline gsl_vector_const_view const getGSLVectorView_const(const vec_map_type v) { - return gsl_vector_const_view_array(v.data(), v.size()); -} -/// take data from a constEigen Matrix and return a transposed gsl view. -inline gsl_matrix_const_view const getGSLMatrixView_const(const map_type m) { - return gsl_matrix_const_view_array(m.data(), m.cols(), m.rows()); -} - } // namespace CurveFitting } // namespace Mantid diff --git a/Framework/CurveFitting/src/CostFunctions/CostFuncFitting.cpp b/Framework/CurveFitting/src/CostFunctions/CostFuncFitting.cpp index 65409a060151..d7fc42ff8f92 100644 --- a/Framework/CurveFitting/src/CostFunctions/CostFuncFitting.cpp +++ b/Framework/CurveFitting/src/CostFunctions/CostFuncFitting.cpp @@ -9,12 +9,11 @@ //---------------------------------------------------------------------- #include "MantidCurveFitting/CostFunctions/CostFuncFitting.h" #include "MantidAPI/IConstraint.h" +#include "MantidCurveFitting/EigenFunctions.h" #include "MantidCurveFitting/EigenJacobian.h" -#include "MantidCurveFitting/GSLFunctions.h" #include "MantidCurveFitting/SeqDomain.h" #include "MantidKernel/Exception.h" -#include #include #include @@ -132,15 +131,8 @@ void CostFuncFitting::calActiveCovarianceMatrix(EigenMatrix &covar, double epsre // calculate the derivatives m_function->functionDeriv(*m_domain, J); - // let the GSL to compute the covariance matrix - EigenMatrix covarTr(covar.tr()); - EigenMatrix tempJTr; - tempJTr = j.transpose(); - gsl_matrix_const_view tempJTrGSL = getGSLMatrixView_const(tempJTr.inspector()); - gsl_matrix_view covarTrGSL = getGSLMatrixView(covarTr.mutator()); - - gsl_multifit_covar(&tempJTrGSL.matrix, epsrel, &covarTrGSL.matrix); - covar = covarTr.tr(); + // let Eigen compute the covariance matrix + covar = covar_from_jacobian(j, epsrel); } /** Calculates covariance matrix diff --git a/Framework/CurveFitting/src/EigenFunctions.cpp b/Framework/CurveFitting/src/EigenFunctions.cpp new file mode 100644 index 000000000000..a298e8714e80 --- /dev/null +++ b/Framework/CurveFitting/src/EigenFunctions.cpp @@ -0,0 +1,70 @@ +// Mantid Repository : https://github.com/mantidproject/mantid +// +// Copyright © 2026 ISIS Rutherford Appleton Laboratory UKRI, +// NScD Oak Ridge National Laboratory, European Spallation Source, +// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS +// SPDX - License - Identifier: GPL - 3.0 + +//---------------------------------------------------------------------- +// Includes +//---------------------------------------------------------------------- +#include "MantidCurveFitting/EigenFunctions.h" + +namespace Mantid::CurveFitting { + +/** Mimics gsl_multifit_covar(J, epsrel, covar) + * @param J :: Jacobian + * @param epsrel :: relative threshold to decide rank deficiency + * @return covariance matrix, rows/cols set to zero for dependent params + */ +Eigen::MatrixXd covar_from_jacobian(const map_type &J, double epsrel) { + if (epsrel < 0.0) { + throw std::invalid_argument("epsrel must be non-negative"); + } + + const Eigen::Index nr = J.rows(); // nr = num rows + const Eigen::Index nc = J.cols(); // nc = num cols + if ((nc == 0) || (nr == 0)) + return Eigen::MatrixXd{}; + + // Pivoted QR Decomposition: JP = QR + Eigen::ColPivHouseholderQR qr(J); + + // R is (nc x np) in general; the useful part for J^T J is (nc x nc) block + Eigen::MatrixXd R = qr.matrixR().topLeftCorner(nc, nc).template triangularView().toDenseMatrix(); + + // Determine rank using the same rule as GSL: compare diag entries to |R_11| + const double r11 = std::abs(R(0, 0)); + Eigen::Index rank = 0; + if (r11 > 0.0) { + for (Eigen::Index k = 0; k < nc; ++k) { + if (std::abs(R(k, k)) > epsrel * r11) { // column considered linerally independant + ++rank; + } else { + break; // with pivoting, following first dependent subsequent cols should also be dependant + } + } + } else { + // R11 == 0, everything dependent + rank = 0; + } + + // Build covariance in the pivoted parameter order + Eigen::MatrixXd cov_pivot = Eigen::MatrixXd::Zero(nc, nc); + + if (rank > 0) { + // cov = (R^T R)^{-1} for the independent cols = R^{-1} R^{-T} + const Eigen::MatrixXd R1 = R.topLeftCorner(rank, rank).template triangularView(); + Eigen::MatrixXd invR1 = R1.inverse(); + Eigen::MatrixXd cov1 = invR1 * invR1.transpose(); + cov_pivot.topLeftCorner(rank, rank) = cov1; + } + + // Unpivot back to original parameter order: + // cov = (J^T J)^{-1} = P (R^T R)^{-1} P^T + const Eigen::PermutationMatrix P = qr.colsPermutation(); + Eigen::MatrixXd cov = P * cov_pivot * P.transpose(); + + return cov; +} + +} // namespace Mantid::CurveFitting diff --git a/Framework/CurveFitting/src/FuncMinimizers/DampedGaussNewtonMinimizer.cpp b/Framework/CurveFitting/src/FuncMinimizers/DampedGaussNewtonMinimizer.cpp index ecb9a1983374..221d1a7e1236 100644 --- a/Framework/CurveFitting/src/FuncMinimizers/DampedGaussNewtonMinimizer.cpp +++ b/Framework/CurveFitting/src/FuncMinimizers/DampedGaussNewtonMinimizer.cpp @@ -18,7 +18,6 @@ #include "MantidKernel/Logger.h" #include -#include namespace Mantid::CurveFitting::FuncMinimisers { @@ -121,9 +120,7 @@ bool DampedGaussNewtonMinimizer::iterate(size_t /*iteration*/) { // Try the stop condition EigenVector p(n); m_leastSquares->getParameters(p); - gsl_vector_view dx_gsl = getGSLVectorView(dx.mutator()); - double dx_norm = gsl_blas_dnrm2(&dx_gsl.vector); - return dx_norm >= m_relTol; + return dx.norm() >= m_relTol; } /// Return current value of the cost function diff --git a/Framework/CurveFitting/src/FuncMinimizers/LevenbergMarquardtMDMinimizer.cpp b/Framework/CurveFitting/src/FuncMinimizers/LevenbergMarquardtMDMinimizer.cpp index 7f9592442a42..ead12ddf2ed5 100644 --- a/Framework/CurveFitting/src/FuncMinimizers/LevenbergMarquardtMDMinimizer.cpp +++ b/Framework/CurveFitting/src/FuncMinimizers/LevenbergMarquardtMDMinimizer.cpp @@ -18,7 +18,6 @@ #include "MantidKernel/Logger.h" #include -#include namespace Mantid::CurveFitting::FuncMinimisers { namespace { @@ -194,15 +193,11 @@ bool LevenbergMarquardtMDMinimizer::iterate(size_t /*iteration*/) { double dL; // der -> - der - 0.5 * hessian * dx - EigenMatrix tempHessianTr = m_costFunction->getHessian().tr(); - const gsl_matrix_const_view tempHessianTrGSL = getGSLMatrixView_const(tempHessianTr.inspector()); - const gsl_vector_const_view dxGSL = getGSLVectorView_const(dx.inspector()); - gsl_vector_view ddGSL = getGSLVectorView(dd.mutator()); - - gsl_blas_dgemv(CblasNoTrans, -0.5, &tempHessianTrGSL.matrix, &dxGSL.vector, 1., &ddGSL.vector); + EigenVector Trdx = m_costFunction->getHessian().tr() * dx; + Trdx *= -0.5; + dd += Trdx; // calculate the linear part of the change in cost function - // dL = - der * dx - 0.5 * dx * hessian * dx - gsl_blas_ddot(&ddGSL.vector, &dxGSL.vector, &dL); + dL = dd.dot(dx); double F1 = m_costFunction->val(); if (verbose) { @@ -216,7 +211,7 @@ bool LevenbergMarquardtMDMinimizer::iterate(size_t /*iteration*/) { if (m_rho >= 0) { EigenVector p(n); m_costFunction->getParameters(p); - double dx_norm = gsl_blas_dnrm2(&dxGSL.vector); + double dx_norm = dx.norm(); if (dx_norm < absError) { if (verbose) { g_log.warning() << "Successful fit, parameters changed by less than " << absError << '\n'; diff --git a/Framework/CurveFitting/src/Functions/ChebfunBase.cpp b/Framework/CurveFitting/src/Functions/ChebfunBase.cpp index 6a2ca754e8ce..c760ab849e5b 100644 --- a/Framework/CurveFitting/src/Functions/ChebfunBase.cpp +++ b/Framework/CurveFitting/src/Functions/ChebfunBase.cpp @@ -11,11 +11,11 @@ #include "MantidCurveFitting/GSLFunctions.h" #include "MantidCurveFitting/HalfComplex.h" -#include -#include #include #include +#include + #include #include #include @@ -684,21 +684,16 @@ std::vector ChebfunBase::roots(const std::vector &a) const { C.set(N + i, lasti, tmp); } - gsl_vector_complex *eigenval = gsl_vector_complex_alloc(N2); - auto workspace = gsl_eigen_nonsymm_alloc(N2); - - EigenMatrix C_tr(C.tr()); - gsl_matrix_view C_tr_gsl = getGSLMatrixView(C_tr.mutator()); - gsl_eigen_nonsymm(&C_tr_gsl.matrix, eigenval, workspace); - gsl_eigen_nonsymm_free(workspace); + Eigen::EigenSolver es(C.mutator()); + const Eigen::VectorXcd evals = es.eigenvalues(); const double Dx = endX() - startX(); bool isFirst = true; double firstIm = 0; for (size_t i = 0; i < N2; ++i) { - auto val = gsl_vector_complex_get(eigenval, i); - double re = GSL_REAL(val); - double im = GSL_IMAG(val); + const std::complex val = evals[static_cast(i)]; + double re = val.real(); + double im = val.imag(); double ab = re * re + im * im; if (fabs(ab - 1.0) > 1e-2) { isFirst = true; @@ -715,8 +710,6 @@ std::vector ChebfunBase::roots(const std::vector &a) const { isFirst = true; } } - gsl_vector_complex_free(eigenval); - return r; } @@ -824,25 +817,24 @@ std::vector ChebfunBase::smooth(const std::vector &xvalues, cons return y; } - // high frequency filter values: smooth decreasing function - auto ri0f = static_cast(i0 + 1); - double xm = (1.0 + ri0f) / 2; - ym /= ri0f; - double a1 = (xy - ri0f * xm * ym) / (xx - ri0f * xm * xm); - double b1 = ym - a1 * xm; - - // std::cerr << "(a1,b1) = (" << a1 << ',' << b1 << ')' << '\n'; - // calculate coeffs of a cubic c3*i^3 + c2*i^2 + c1*i + c0 // which will replace the linear a1*i + b1 in building the // second part of the filter double c0, c1, c2, c3; { + // high frequency filter values: smooth decreasing function + auto ri0f = static_cast(i0 + 1); + double xm = (1.0 + ri0f) / 2; + ym /= ri0f; + auto x0 = double(i0 + 1); auto x1 = double(n + 1); double sigma = g_tolerance / noise / 10; double s = sigma / (1.0 - sigma); double m1 = log(s); + double a1 = (xy - ri0f * xm * ym) / (xx - ri0f * xm * xm); + double b1 = ym - a1 * xm; + // std::cerr << "(a1,b1) = (" << a1 << ',' << b1 << ')' << '\n'; double m0 = a1 * x0 + b1; if (a1 < 0.0) { c3 = 0.0; diff --git a/Framework/CurveFitting/test/CostFunctions/LeastSquaresTest.h b/Framework/CurveFitting/test/CostFunctions/LeastSquaresTest.h index 419d78d9c4b1..d60f343d3386 100644 --- a/Framework/CurveFitting/test/CostFunctions/LeastSquaresTest.h +++ b/Framework/CurveFitting/test/CostFunctions/LeastSquaresTest.h @@ -22,7 +22,6 @@ #include "MantidCurveFitting/Functions/UserFunction.h" #include "MantidCurveFitting/GSLFunctions.h" -#include #include using namespace Mantid; @@ -201,15 +200,11 @@ class LeastSquaresTest : public CxxTest::TestSuite { dx.set(1, -0.2); double L; // = d*dx + 0.5 * dx * H * dx + EigenVector Trdx = H.tr() * dx; + Trdx *= 0.5; + g += Trdx; + L = g.dot(dx); - EigenMatrix temp_H_tr = H.tr(); - const gsl_matrix_const_view temp_H_tr_gsl = getGSLMatrixView_const(temp_H_tr.inspector()); - const gsl_vector_const_view dx_gsl = getGSLVectorView_const(dx.inspector()); - gsl_vector_view g_gsl = getGSLVectorView(g.mutator()); - - gsl_blas_dgemv(CblasNoTrans, 0.5, &temp_H_tr_gsl.matrix, &dx_gsl.vector, 1., &g_gsl.vector); - - gsl_blas_ddot(&g_gsl.vector, &dx_gsl.vector, &L); TS_ASSERT_DELTA(L, -0.145, 1e-10); // L + costFun->val() == 0 } diff --git a/Framework/CurveFitting/test/EigenFunctionsTest.h b/Framework/CurveFitting/test/EigenFunctionsTest.h new file mode 100644 index 000000000000..e1c997e14d19 --- /dev/null +++ b/Framework/CurveFitting/test/EigenFunctionsTest.h @@ -0,0 +1,112 @@ +// Mantid Repository : https://github.com/mantidproject/mantid +// +// Copyright © 2026 ISIS Rutherford Appleton Laboratory UKRI, +// NScD Oak Ridge National Laboratory, European Spallation Source, +// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS +// SPDX - License - Identifier: GPL - 3.0 + +#pragma once + +#include + +#include "MantidCurveFitting/EigenFunctions.h" + +#include +#include +#include + +namespace { +static int is_zero(double x) { return x == 0.0; } + +static int param_is_dropped(const gsl_matrix *covar, size_t i) { + size_t n = covar->size1; + for (size_t k = 0; k < n; ++k) { + if (!is_zero(gsl_matrix_get(covar, i, k))) + return 0; // row not all zero + if (!is_zero(gsl_matrix_get(covar, k, i))) + return 0; // col not all zero + } + return 1; +} + +static int param_is_dropped(const Eigen::MatrixXd &covar, size_t i) { + size_t n = covar.rows(); + for (size_t k = 0; k < n; ++k) { + if (!is_zero(covar(i, k))) + return 0; + if (!is_zero(covar(k, i))) + return 0; + } + return 1; +} + +// As per the gsl docs, parameter i is considered dropped if its row and column are zero +// https://tool.oschina.net/uploads/apidocs/gsl/Computing-the-covariance-matrix-of-best-fit-parameters.html +static size_t count_dropped_params(const gsl_matrix *covar) { + size_t n = covar->size1; + size_t dropped = 0; + for (size_t i = 0; i < n; ++i) + dropped += (size_t)param_is_dropped(covar, i); + return dropped; +} + +static size_t count_dropped_params(const Eigen::MatrixXd &covar) { + size_t n = covar.rows(); + size_t dropped = 0; + for (size_t i = 0; i < n; ++i) + dropped += (size_t)param_is_dropped(covar, i); + return dropped; +} + +// Simple Jacobian with two columns that become dependent when J11 = 0 +static gsl_matrix *make_J_2x2(double J11) { + gsl_matrix *J = gsl_matrix_alloc(2, 2); + gsl_matrix_set(J, 0, 0, 1.0); + gsl_matrix_set(J, 1, 0, 1.0); + gsl_matrix_set(J, 0, 1, 0.0); + gsl_matrix_set(J, 1, 1, J11); + return J; +} +} // namespace + +class EigenFunctionsTest : public CxxTest::TestSuite { +public: + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static EigenFunctionsTest *createSuite() { return new EigenFunctionsTest(); } + static void destroySuite(EigenFunctionsTest *suite) { delete suite; } + + void assert_gsl_eigen_equal(const gsl_matrix *gslM, const Eigen::MatrixXd &eM) { + if (gslM->size1 != (size_t)eM.rows() || gslM->size2 != (size_t)eM.cols()) { + throw std::invalid_argument("Matricies are not of equal size"); + } + for (size_t i = 0; i < gslM->size2; i++) { + for (size_t j = 0; j < gslM->size1; j++) { + TS_ASSERT_EQUALS(gsl_matrix_get(gslM, i, j), eM(i, j)) + } + } + } + + void eigen_gsl_equivalence_impl(double J11, double epsrel) { + Mantid::CurveFitting::EigenMatrix J{{1, 0}, {1, J11}}; + + gsl_matrix *JGsl = make_J_2x2(J11); + gsl_matrix *covarGsl = gsl_matrix_calloc(2, 2); + + auto covar = Mantid::CurveFitting::covar_from_jacobian(J.mutator(), epsrel); + gsl_multifit_covar(JGsl, epsrel, covarGsl); + + assert_gsl_eigen_equal(covarGsl, covar); + TS_ASSERT_EQUALS(count_dropped_params(covarGsl), count_dropped_params(covar)) + + gsl_matrix_free(covarGsl); + gsl_matrix_free(JGsl); + } + + void test_esprel_large() { eigen_gsl_equivalence_impl(1e-8, 1e-8); } + + void test_epsrel_small() { eigen_gsl_equivalence_impl(1e-8, 1e-9); } + + void test_epsrel_zero() { eigen_gsl_equivalence_impl(1e-8, 0); } + + void test_epsrel_zero_linear_dependence() { eigen_gsl_equivalence_impl(0, 0); } +}; diff --git a/Framework/CurveFitting/test/EigenToGSLTest.h b/Framework/CurveFitting/test/EigenToGSLTest.h deleted file mode 100644 index 4edae0df41b4..000000000000 --- a/Framework/CurveFitting/test/EigenToGSLTest.h +++ /dev/null @@ -1,110 +0,0 @@ -// Mantid Repository : https://github.com/mantidproject/mantid -// -// Copyright © 2022 ISIS Rutherford Appleton Laboratory UKRI, -// NScD Oak Ridge National Laboratory, European Spallation Source, -// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS -// SPDX - License - Identifier: GPL - 3.0 + -#pragma once - -#include - -#include -#include -#include -#include - -using namespace Mantid::CurveFitting; - -namespace { -Eigen::MatrixXd GenerateMatrix(int i, int j, bool random = false) { - std::srand((unsigned int)time(0)); - if (random) { - return Eigen::MatrixXd::Random(i, j).unaryExpr([](double x) -> double { return round(abs(x * 10)); }); - } else { - double n = 0; - return Eigen::MatrixXd::Zero(i, j).unaryExpr([&n](double x) -> double { return x + n++; }); - } -} - -double *createArray(const int &nArraySize, bool random) { - std::srand((unsigned int)time(0)); - double *array = new double[nArraySize]; - for (int i = 0; i < nArraySize; ++i) - random ? array[i] = rand() % nArraySize : array[i] = i; - return array; -} - -Eigen::VectorXd createVecFromArray(double *array, const int &nElements) { - Eigen::Map vec(array, nElements, 1); - return vec; -} - -Eigen::VectorXd GenerateVector(int i, bool random = false) { return createVecFromArray(createArray(i, random), i); } - -} // namespace - -class EigenToGSLTest : public CxxTest::TestSuite { -public: - void test_EigenMatrix_to_GSL() { - EigenMatrix m(10, 5); - m = GenerateMatrix(10, 5); - - gsl_matrix_view m_gsl_view = getGSLMatrixView(m.mutator()); - gsl_matrix *m_gsl = &m_gsl_view.matrix; - - EigenMatrix m_tr = m.tr(); - - for (size_t i = 0; i < m.size1(); i++) { - for (size_t j = 0; j < m.size2(); j++) { - TS_ASSERT_EQUALS(gsl_matrix_get(m_gsl, j, i), m_tr(j, i)); - } - } - - // check reference is not broken - gsl_matrix_set(m_gsl, 0, 0, -1.); - TS_ASSERT_EQUALS(gsl_matrix_get(m_gsl, 0, 0), m(0, 0)); - } - - void test_EigenMatrix_to_GSL_const() { - EigenMatrix m(10, 5); - m = GenerateMatrix(10, 5); - - EigenMatrix m_tr = m.tr(); - - const gsl_matrix_const_view m_gsl_view = getGSLMatrixView_const(m_tr.inspector()); - const gsl_matrix *m_gsl = &m_gsl_view.matrix; - - for (size_t i = 0; i < m.size1(); i++) { - for (size_t j = 0; j < m.size2(); j++) { - TS_ASSERT_EQUALS(gsl_matrix_get(m_gsl, i, j), m(i, j)); - } - } - } - - void test_EigenVector_to_GSL() { - auto vec = GenerateVector(10); - EigenVector v(&vec); - - gsl_vector_view v_gsl = getGSLVectorView(v.mutator()); - - for (size_t i = 0; i < v.size(); i++) { - TS_ASSERT_EQUALS(gsl_vector_get(&v_gsl.vector, i), v[i]); - } - - // check reference is not broken - gsl_vector_set(&v_gsl.vector, 0, -1.); - TS_ASSERT_EQUALS(gsl_vector_get(&v_gsl.vector, 0), v[0]); - } - - void test_EigenVector_to_GSL_const() { - auto vec = GenerateVector(10); - - const EigenVector v(&vec); - - const gsl_vector_const_view v_gsl = getGSLVectorView_const(v.inspector()); - - for (size_t i = 0; i < v.size(); i++) { - TS_ASSERT_EQUALS(gsl_vector_get(&v_gsl.vector, i), v[i]); - } - } -}; diff --git a/Testing/SystemTests/tests/framework/SNSPowderRedux.py b/Testing/SystemTests/tests/framework/SNSPowderRedux.py index 7e944508fc6c..4f242d531f6b 100644 --- a/Testing/SystemTests/tests/framework/SNSPowderRedux.py +++ b/Testing/SystemTests/tests/framework/SNSPowderRedux.py @@ -49,10 +49,9 @@ def _skip_test(): """Helper function to determine if we run the test""" - import platform # Only runs on RHEL6 at the moment - return "Linux" not in platform.platform() + return False def getSaveDir(): diff --git a/Testing/SystemTests/tests/framework/reference/PG3_4866_reference.gsa.md5 b/Testing/SystemTests/tests/framework/reference/PG3_4866_reference.gsa.md5 index 4bc3f460cfb0..3235fa57946f 100644 --- a/Testing/SystemTests/tests/framework/reference/PG3_4866_reference.gsa.md5 +++ b/Testing/SystemTests/tests/framework/reference/PG3_4866_reference.gsa.md5 @@ -1 +1 @@ -bb32cf1db4398867e36ba9e5f427d4dc +176baa5df804b616e54233fdaf35498f diff --git a/Testing/SystemTests/tests/framework/reference/PG3_4866_reference.nxs.md5 b/Testing/SystemTests/tests/framework/reference/PG3_4866_reference.nxs.md5 new file mode 100644 index 000000000000..df6f887beace --- /dev/null +++ b/Testing/SystemTests/tests/framework/reference/PG3_4866_reference.nxs.md5 @@ -0,0 +1 @@ +7d539aef135cea16086b53e09a05971e diff --git a/buildconfig/CMake/CppCheck_Suppressions.txt.in b/buildconfig/CMake/CppCheck_Suppressions.txt.in index 4523940879c8..6f8d9279f324 100644 --- a/buildconfig/CMake/CppCheck_Suppressions.txt.in +++ b/buildconfig/CMake/CppCheck_Suppressions.txt.in @@ -79,7 +79,6 @@ containerOutOfBounds:${CMAKE_SOURCE_DIR}/Framework/Crystal/src/SaveHKL.cpp:606 unreadVariable:${CMAKE_SOURCE_DIR}/Framework/CurveFitting/src/Algorithms/Fit1D.cpp:379 derefInvalidIteratorRedundantCheck:${CMAKE_SOURCE_DIR}/Framework/CurveFitting/src/ExcludeRangeFinder.cpp:77 useStlAlgorithm:${CMAKE_SOURCE_DIR}/Framework/CurveFitting/src/Functions/BSpline.cpp:146 -variableScope:${CMAKE_SOURCE_DIR}/Framework/CurveFitting/src/Functions/ChebfunBase.cpp:832 duplicateCondition:${CMAKE_SOURCE_DIR}/Framework/CurveFitting/src/Functions/CrystalFieldFunction.cpp:120 constParameter:${CMAKE_SOURCE_DIR}/Framework/CurveFitting/src/Functions/DynamicKuboToyabe.cpp:69 useStlAlgorithm:${CMAKE_SOURCE_DIR}/Framework/DataHandling/src/LoadHFIRSANS.cpp:432