Skip to content

Commit

Permalink
Add XScaling parameter to TabulatedFunction
Browse files Browse the repository at this point in the history
Refs #11752
  • Loading branch information
DanNixon committed May 13, 2015
1 parent 5b15be5 commit efc78ba
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 15 deletions.
Expand Up @@ -102,7 +102,7 @@ class DLLExport TabulatedFunction : public API::ParamFunction,
void clear() const;

/// Evaluate the function for a list of arguments and given scaling factor
void eval(double scaling, double shift, double *out, const double *xValues,
void eval(double scaling, double shift, double xscale, double *out, const double *xValues,
const size_t nData) const;

/// Fill in the x and y value containers (m_xData and m_yData)
Expand Down
27 changes: 19 additions & 8 deletions Code/Mantid/Framework/CurveFitting/src/TabulatedFunction.cpp
Expand Up @@ -30,13 +30,14 @@ const int TabulatedFunction::defaultIndexValue = 0;
TabulatedFunction::TabulatedFunction() : m_setupFinished(false) {
declareParameter("Scaling", 1.0, "A scaling factor");
declareParameter("Shift", 0.0, "Shift in the abscissa");
declareParameter("XScaling", 1.0, "Scaling factor in X");
declareAttribute("FileName", Attribute("", true));
declareAttribute("Workspace", Attribute(""));
declareAttribute("WorkspaceIndex", Attribute(defaultIndexValue));
}

/// Evaluate the function for a list of arguments and given scaling factor
void TabulatedFunction::eval(double scaling, double xshift, double *out,
void TabulatedFunction::eval(double scaling, double xshift, double xscale, double *out,
const double *xValues, const size_t nData) const {
if (nData == 0)
return;
Expand All @@ -46,10 +47,11 @@ void TabulatedFunction::eval(double scaling, double xshift, double *out,
if (size() == 0)
return;

// shift the domain over which the function is defined
// shift and scale the domain over which the function is defined
std::vector<double> xData(m_xData);
for (std::vector<double>::iterator it = xData.begin(); it != xData.end();
++it) {
*it *= xscale;
*it += xshift;
}

Expand Down Expand Up @@ -100,7 +102,8 @@ void TabulatedFunction::function1D(double *out, const double *xValues,
const size_t nData) const {
const double scaling = getParameter("Scaling");
const double xshift = getParameter("Shift");
eval(scaling, xshift, out, xValues, nData);
const double xscale = getParameter("XScaling");
eval(scaling, xshift, xscale, out, xValues, nData);
}

/**
Expand All @@ -115,24 +118,32 @@ void TabulatedFunction::functionDeriv1D(API::Jacobian *out,
const size_t nData) {
const double scaling = getParameter("Scaling");
const double xshift = getParameter("Shift");
const double xscale = getParameter("XScaling");
std::vector<double> tmp(nData);
// derivative with respect to Scaling parameter
eval(1.0, xshift, tmp.data(), xValues, nData);
eval(1.0, xshift, xscale, tmp.data(), xValues, nData);
for (size_t i = 0; i < nData; ++i) {
out->set(i, 0, tmp[i]);
}

// There is no unique definition for the partial derivative with respect
// to the Shift parameter. Here we take the central difference,
const double dx =
(xValues[nData - 1] - xValues[0]) / static_cast<double>(nData);
std::vector<double> tmpplus(nData);
eval(scaling, xshift + dx, tmpplus.data(), xValues, nData);
std::vector<double> tmpminus(nData);
eval(scaling, xshift - dx, tmpminus.data(), xValues, nData);

// There is no unique definition for the partial derivative with respect
// to the Shift parameter. Here we take the central difference,
eval(scaling, xshift + dx, xscale, tmpplus.data(), xValues, nData);
eval(scaling, xshift - dx, xscale, tmpminus.data(), xValues, nData);
for (size_t i = 0; i < nData; ++i) {
out->set(i, 1, (tmpplus[i] - tmpminus[i]) / (2 * dx));
}

eval(scaling, xshift, xscale + dx, tmpplus.data(), xValues, nData);
eval(scaling, xshift, xscale - dx, tmpminus.data(), xValues, nData);
for (size_t i = 0; i < nData; ++i) {
out->set(i, 2, (tmpplus[i] - tmpminus[i]) / (2 * dx));
}
}

/// Clear all data
Expand Down
16 changes: 10 additions & 6 deletions Code/Mantid/Framework/CurveFitting/test/TabulatedFunctionTest.h
Expand Up @@ -50,19 +50,19 @@ class TabulatedFunctionTest : public CxxTest::TestSuite
UserFunction fun;
fun.setAttributeValue("Formula","exp(-x*x)");
fun.function( x, y );

std::ofstream fil(m_asciiFileName.c_str());
for(size_t i = 0; i < x.size(); ++i)
{
fil << x[i] << ' ' << y[i] << std::endl;
}

}

~TabulatedFunctionTest()
{
Poco::File hAscii(m_asciiFileName);
if( hAscii.exists() )
if( hAscii.exists() )
{
hAscii.remove();
}
Expand Down Expand Up @@ -205,12 +205,14 @@ class TabulatedFunctionTest : public CxxTest::TestSuite
TS_ASSERT_EQUALS( fun.getParameter( "Scaling" ), 3.3 );
fun.setParameter( "Shift", 0.0 );
TS_ASSERT_EQUALS( fun.getParameter( "Shift" ), 0.0 );
fun.setParameter( "XScaling", 1.0 );
TS_ASSERT_EQUALS( fun.getParameter( "XScaling" ), 1.0 );
FunctionDomain1DVector x(-5.0, 5.0, 83);

FunctionValues y( x );
fun.function( x, y );

Mantid::CurveFitting::Jacobian jac(x.size(),2);
Mantid::CurveFitting::Jacobian jac(x.size(),3);
fun.functionDeriv(x, jac);

for(size_t i = 0; i < x.size(); ++i)
Expand Down Expand Up @@ -239,28 +241,30 @@ class TabulatedFunctionTest : public CxxTest::TestSuite

void test_factory_create_from_file()
{
std::string inif = "name=TabulatedFunction,FileName=\"" + m_nexusFileName + "\",WorkspaceIndex=17,Scaling=2,Shift=0.02";
std::string inif = "name=TabulatedFunction,FileName=\"" + m_nexusFileName + "\",WorkspaceIndex=17,Scaling=2,Shift=0.02,XScaling=0.2";
auto funf = Mantid::API::FunctionFactory::Instance().createInitialized(inif);
TS_ASSERT( funf );
TS_ASSERT_EQUALS( funf->getAttribute("Workspace").asString(), "");
TS_ASSERT_EQUALS( funf->getAttribute("WorkspaceIndex").asInt(), 17);
TS_ASSERT_EQUALS( funf->getAttribute("FileName").asUnquotedString(), m_nexusFileName);
TS_ASSERT_EQUALS( funf->getParameter("Scaling"), 2.0);
TS_ASSERT_EQUALS( funf->getParameter("Shift"), 0.02);
TS_ASSERT_EQUALS( funf->getParameter("XScaling"), 0.2);
}

void test_factory_create_from_workspace()
{
auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(Fun(),1,-5.0,5.0,0.1,false);
AnalysisDataService::Instance().add( "TABULATEDFUNCTIONTEST_WS", ws );
std::string inif = "name=TabulatedFunction,Workspace=TABULATEDFUNCTIONTEST_WS,WorkspaceIndex=71,Scaling=3.14,Shift=0.02";
std::string inif = "name=TabulatedFunction,Workspace=TABULATEDFUNCTIONTEST_WS,WorkspaceIndex=71,Scaling=3.14,Shift=0.02,XScaling=0.2";
auto funf = Mantid::API::FunctionFactory::Instance().createInitialized(inif);
TS_ASSERT( funf );
TS_ASSERT_EQUALS( funf->getAttribute("Workspace").asString(), "TABULATEDFUNCTIONTEST_WS");
TS_ASSERT_EQUALS( funf->getAttribute("WorkspaceIndex").asInt(), 71);
TS_ASSERT_EQUALS( funf->getAttribute("FileName").asUnquotedString(), "");
TS_ASSERT_EQUALS( funf->getParameter("Scaling"), 3.14);
TS_ASSERT_EQUALS( funf->getParameter("Shift"), 0.02);
TS_ASSERT_EQUALS( funf->getParameter("XScaling"), 0.2);
AnalysisDataService::Instance().clear();
}

Expand Down

0 comments on commit efc78ba

Please sign in to comment.