diff --git a/Framework/CurveFitting/src/ComplexMatrix.cpp b/Framework/CurveFitting/src/ComplexMatrix.cpp
index 0f0759a1111c89c0da8805d82dd5cfc4ddebcea7..f3cd9ea3eb9aa2f1c9338e8bd4e07d680d9ad264 100644
--- a/Framework/CurveFitting/src/ComplexMatrix.cpp
+++ b/Framework/CurveFitting/src/ComplexMatrix.cpp
@@ -301,8 +301,6 @@ void ComplexMatrix::eigenSystemHermitian(GSLVector &eigenValues,
   eigenValues.resize(n);
   eigenVectors.resize(n, n);
   auto workspace = gsl_eigen_hermv_alloc(n);
-  // RT: I think there is a bug in this function. It returns garbage in
-  // eigenvectors in a repeated call.
   gsl_eigen_hermv(gsl(), eigenValues.gsl(), eigenVectors.gsl(), workspace);
   gsl_eigen_hermv_free(workspace);
 }
diff --git a/Framework/CurveFitting/src/GSLVector.cpp b/Framework/CurveFitting/src/GSLVector.cpp
index afe73a1b750506c2ead052320e6c8b4752db2ee1..62213159dbc6eefe3fa52366583b0f565e1f1e98 100644
--- a/Framework/CurveFitting/src/GSLVector.cpp
+++ b/Framework/CurveFitting/src/GSLVector.cpp
@@ -272,6 +272,7 @@ void GSLVector::sort(const std::vector<size_t> &indices) {
     data[i] = m_data[indices[i]];
   }
   std::swap(m_data, data);
+  m_view = gsl_vector_view_array(m_data.data(), m_data.size());
 }
 
 /// Create a new GSLVector and move all data to it. Destroys this vector.
diff --git a/Framework/CurveFitting/src/IMWDomainCreator.cpp b/Framework/CurveFitting/src/IMWDomainCreator.cpp
index d2081c2ded0e494603103293e059eb8c472183e7..9a2c956805e59e0722cad8fd30986383613b16cd 100644
--- a/Framework/CurveFitting/src/IMWDomainCreator.cpp
+++ b/Framework/CurveFitting/src/IMWDomainCreator.cpp
@@ -437,58 +437,75 @@ void IMWDomainCreator::addFunctionValuesToWS(
   function->function(*domain, *resultValues);
 
   size_t nParams = function->nParams();
-  // and errors
-  SimpleJacobian J(nData, nParams);
-  try {
-    function->functionDeriv(*domain, J);
-  } catch (...) {
-    function->calNumericalDeriv(*domain, J);
-  }
 
   // the function should contain the parameter's covariance matrix
   auto covar = function->getCovarianceMatrix();
-
-  if (covar) {
-    // if the function has a covariance matrix attached - use it for the errors
-    const Kernel::Matrix<double> &C = *covar;
-    // The formula is E = J * C * J^T
-    // We don't do full 3-matrix multiplication because we only need the
-    // diagonals of E
-    std::vector<double> E(nData);
-    for (size_t k = 0; k < nData; ++k) {
-      double s = 0.0;
-      for (size_t i = 0; i < nParams; ++i) {
-        double tmp = J.get(k, i);
-        s += C[i][i] * tmp * tmp;
-        for (size_t j = i + 1; j < nParams; ++j) {
-          s += J.get(k, i) * C[i][j] * J.get(k, j) * 2;
-        }
+  bool hasErrors = false;
+  if (!covar) {
+    for (size_t j = 0; j < nParams; ++j) {
+      if (function->getError(j) != 0.0) {
+        hasErrors = true;
+        break;
       }
-      E[k] = s;
     }
+  }
 
-    double chi2 = function->getChiSquared();
-    auto &yValues = ws->mutableY(wsIndex);
-    auto &eValues = ws->mutableE(wsIndex);
-    for (size_t i = 0; i < nData; i++) {
-      yValues[i] = resultValues->getCalculated(i);
-      eValues[i] = std::sqrt(E[i] * chi2);
+  if (covar || hasErrors) {
+    // and errors
+    SimpleJacobian J(nData, nParams);
+    try {
+      function->functionDeriv(*domain, J);
+    } catch (...) {
+      function->calNumericalDeriv(*domain, J);
     }
+    if (covar) {
+      // if the function has a covariance matrix attached - use it for the errors
+      const Kernel::Matrix<double> &C = *covar;
+      // The formula is E = J * C * J^T
+      // We don't do full 3-matrix multiplication because we only need the
+      // diagonals of E
+      std::vector<double> E(nData);
+      for (size_t k = 0; k < nData; ++k) {
+        double s = 0.0;
+        for (size_t i = 0; i < nParams; ++i) {
+          double tmp = J.get(k, i);
+          s += C[i][i] * tmp * tmp;
+          for (size_t j = i + 1; j < nParams; ++j) {
+            s += J.get(k, i) * C[i][j] * J.get(k, j) * 2;
+          }
+        }
+        E[k] = s;
+      }
 
-  } else {
-    // otherwise use the parameter errors which is OK for uncorrelated
-    // parameters
-    auto &yValues = ws->mutableY(wsIndex);
-    auto &eValues = ws->mutableE(wsIndex);
-    for (size_t i = 0; i < nData; i++) {
-      yValues[i] = resultValues->getCalculated(i);
-      double err = 0.0;
-      for (size_t j = 0; j < nParams; ++j) {
-        double d = J.get(i, j) * function->getError(j);
-        err += d * d;
+      double chi2 = function->getChiSquared();
+      auto &yValues = ws->mutableY(wsIndex);
+      auto &eValues = ws->mutableE(wsIndex);
+      for (size_t i = 0; i < nData; i++) {
+        yValues[i] = resultValues->getCalculated(i);
+        eValues[i] = std::sqrt(E[i] * chi2);
+      }
+
+    } else {
+      // otherwise use the parameter errors which is OK for uncorrelated
+      // parameters
+      auto &yValues = ws->mutableY(wsIndex);
+      auto &eValues = ws->mutableE(wsIndex);
+      for (size_t i = 0; i < nData; i++) {
+        yValues[i] = resultValues->getCalculated(i);
+        double err = 0.0;
+        for (size_t j = 0; j < nParams; ++j) {
+          double d = J.get(i, j) * function->getError(j);
+          err += d * d;
+        }
+        eValues[i] = std::sqrt(err);
       }
-      eValues[i] = std::sqrt(err);
     }
+  } else {
+    // No errors
+      auto &yValues = ws->mutableY(wsIndex);
+      for (size_t i = 0; i < nData; i++) {
+        yValues[i] = resultValues->getCalculated(i);
+      }
   }
 }
 
diff --git a/Framework/CurveFitting/test/Functions/CrystalFieldHeatCapacityTest.h b/Framework/CurveFitting/test/Functions/CrystalFieldHeatCapacityTest.h
index d78f5edce30e2f601d2f3f984266361c3be2f7cd..379d12b6c59e5c081642fe02370b7b33ca3d6c56 100644
--- a/Framework/CurveFitting/test/Functions/CrystalFieldHeatCapacityTest.h
+++ b/Framework/CurveFitting/test/Functions/CrystalFieldHeatCapacityTest.h
@@ -3,11 +3,14 @@
 
 #include <cxxtest/TestSuite.h>
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FunctionDomain1D.h"
 #include "MantidAPI/FunctionValues.h"
 #include "MantidAPI/FunctionFactory.h"
 #include "MantidAPI/ParameterTie.h"
+#include "MantidCurveFitting/Algorithms/EvaluateFunction.h"
 #include "MantidCurveFitting/Functions/CrystalFieldHeatCapacity.h"
+#include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
 using namespace Mantid;
 using namespace Mantid::API;
@@ -75,6 +78,32 @@ public:
     }
     TS_ASSERT_EQUALS(nTies, 1); // Fixed values not ties.
   }
+
+  void test_evaluate_function() {
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceBinned(1, 100, 1.0, 3.0);
+    std::string fun = "name=CrystalFieldHeatCapacity,Ion=Ce,Symmetry=C2v,"
+        "B20=0.37,B22=3.9, B40=-0.03,B42=-0.1,B44=-0.12, "
+        "ties=(BmolX=0,BmolY=0,BmolZ=0,BextX=0,BextY=0,BextZ=BextX)";
+
+    Algorithms::EvaluateFunction eval;
+    eval.initialize();
+    eval.setProperty("Function", fun);
+    eval.setProperty("InputWorkspace", ws);
+    eval.setPropertyValue("OutputWorkspace", "out");
+    eval.execute();
+
+    auto out =
+        API::AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("out");
+
+    auto &y = out->histogram(1).counts();
+    TS_ASSERT_DELTA(y[10], 0.0305, 1e-4);
+    TS_ASSERT_DELTA(y[30], 3.7753, 1e-4);
+    TS_ASSERT_DELTA(y[70], 5.1547, 1e-4);
+    TS_ASSERT_DELTA(y[99], 3.4470, 1e-4);
+
+    API::AnalysisDataService::Instance().clear();
+  }
+
 };
 
 #endif /*CRYSTALFIELDHEATCAPACITYTEST_H_*/
diff --git a/scripts/test/CrystalFieldTest.py b/scripts/test/CrystalFieldTest.py
index 4335307448c4bebc32059000d0dfefc11d706a0a..2662c3366b32908827cfa767c1c80cec3876a6fc 100644
--- a/scripts/test/CrystalFieldTest.py
+++ b/scripts/test/CrystalFieldTest.py
@@ -1331,8 +1331,8 @@ class CrystalFieldFitTest(unittest.TestCase):
                       Temperature=44.0, FWHM=1.0, ResolutionModel=rm, FWHMVariation=0.3)
         sp = cf.getSpectrum()
         self.assertAlmostEqual(cf.peaks.param[0]['FWHM'], 1.0, 8)
-        self.assertAlmostEqual(cf.peaks.param[1]['FWHM'], 1.58101468, 8)
-        self.assertAlmostEqual(cf.peaks.param[2]['FWHM'], 1.884945866, 8)
+        self.assertAlmostEqual(cf.peaks.param[1]['FWHM'], 1.58958, 1)
+        self.assertAlmostEqual(cf.peaks.param[2]['FWHM'], 1.85644, 1)
 
     def test_ResolutionModel_set_multi(self):
         from CrystalField import ResolutionModel, CrystalField, CrystalFieldFit