Skip to content

Commit

Permalink
refs #5633. New parameter function produced
Browse files Browse the repository at this point in the history
  • Loading branch information
OwenArnold committed Jul 23, 2012
1 parent 4cd36cd commit 0b7a4be
Show file tree
Hide file tree
Showing 4 changed files with 283 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Code/Mantid/Framework/CurveFitting/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ set ( SRC_FILES
src/ParDomain.cpp
src/PlotPeakByLogValue.cpp
src/ProductFunction.cpp
src/ProductLinearExp.cpp
src/Quadratic.cpp
src/QuadraticBackground.cpp
src/Resolution.cpp
Expand Down Expand Up @@ -131,6 +132,7 @@ set ( INC_FILES
inc/MantidCurveFitting/ParDomain.h
inc/MantidCurveFitting/PlotPeakByLogValue.h
inc/MantidCurveFitting/ProductFunction.h
inc/MantidCurveFitting/ProductLinearExp.h
inc/MantidCurveFitting/Quadratic.h
inc/MantidCurveFitting/QuadraticBackground.h
inc/MantidCurveFitting/Resolution.h
Expand Down Expand Up @@ -193,6 +195,7 @@ set ( TEST_FILES
test/PRConjugateGradientTest.h
test/PlotPeakByLogValueTest.h
test/ProductFunctionTest.h
test/ProductLinearExpTest.h
test/QuadraticBackgroundTest.h
test/QuadraticTest.h
test/ResolutionTest.h
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#ifndef MANTID_CURVEFITTING_PRODUCTLINEAREXP_H_
#define MANTID_CURVEFITTING_PRODUCTLINEAREXP_H_

#include "MantidKernel/System.h"
#include "MantidAPI/ParamFunction.h"
#include "MantidAPI/IFunction1D.h"

namespace Mantid
{
namespace CurveFitting
{

/** ProductLinearExp : Function that evauates the product of an exponential and linear function.
Copyright © 2012 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
This file is part of Mantid.
Mantid is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Mantid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport ProductLinearExp : public API::ParamFunction, public API::IFunction1D
{
public:
ProductLinearExp();
virtual ~ProductLinearExp();

std::string name()const{return "ProductLinearExp";}

virtual const std::string category() const { return "Calibrate";}

protected:
virtual void functionDeriv1D(API::Jacobian* out, const double* xValues, const size_t nData);
virtual void function1D(double* out, const double* xValues, const size_t nData) const;
};


} // namespace CurveFitting
} // namespace Mantid

#endif /* MANTID_CURVEFITTING_PRODUCTLINEAREXP_H_ */
54 changes: 54 additions & 0 deletions Code/Mantid/Framework/CurveFitting/src/ProductLinearExp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include "MantidCurveFitting/ProductLinearExp.h"
#include "MantidCurveFitting/ExpDecay.h"
#include "MantidCurveFitting/LinearBackground.h"
#include "MantidCurveFitting/ProductFunction.h"
#include "MantidAPI/FunctionFactory.h"

namespace Mantid
{
namespace CurveFitting
{

using namespace Kernel;
using namespace API;

DECLARE_FUNCTION(ProductLinearExp)

//----------------------------------------------------------------------------------------------
/** Constructor
*/
ProductLinearExp::ProductLinearExp()
{
declareParameter("A0", 1.0);
declareParameter("A1", 1.0);
declareParameter("Height", 1.0);
declareParameter("Lifetime", 1.0);
}

//----------------------------------------------------------------------------------------------
/** Destructor
*/
ProductLinearExp::~ProductLinearExp()
{
}

void ProductLinearExp::functionDeriv1D(API::Jacobian* out, const double* xValues, const size_t nData)
{

}

void ProductLinearExp::function1D(double* out, const double* xValues, const size_t nData) const
{
double A0 = getParameter("A0");
double A1 = getParameter("A1");
double Height = getParameter("Height");
double Lifetime = getParameter("Lifetime");

for(size_t i = 0; i < nData; ++i)
{
out[i] = ((A1 * xValues[i]) + A0)* Height * std::exp(-xValues[i]/Lifetime);
}
}

} // namespace CurveFitting
} // namespace Mantid
172 changes: 172 additions & 0 deletions Code/Mantid/Framework/CurveFitting/test/ProductLinearExpTest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
#ifndef MANTID_CURVEFITTING_PRODUCTLINEAREXPTEST_H_
#define MANTID_CURVEFITTING_PRODUCTLINEAREXPTEST_H_

#include <cxxtest/TestSuite.h>

#include "MantidCurveFitting/ProductLinearExp.h"
#include "MantidCurveFitting/ExpDecay.h"
#include "MantidCurveFitting/LinearBackground.h"
#include "MantidCurveFitting/ProductFunction.h"
#include "MantidAPI/FunctionDomain1D.h"
#include "MantidAPI/FunctionValues.h"
#include <algorithm>

using namespace Mantid::CurveFitting;
using namespace Mantid::API;

class ProductLinearExpTest : public CxxTest::TestSuite
{
private:

/// Helper type to generate number for a std::generate call.
class LinearIncrementingAssignment
{
private:
const double m_step;
double m_current;
public:
LinearIncrementingAssignment(double min, double step) : m_current(min), m_step(step)
{
}
double operator() ()
{
double temp = m_current;
m_current += m_step;
return temp;
}
};

public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static ProductLinearExpTest *createSuite() { return new ProductLinearExpTest(); }
static void destroySuite( ProductLinearExpTest *suite ) { delete suite; }

void test_name()
{
ProductLinearExp func;
TS_ASSERT_EQUALS("ProductLinearExp", func.name());
}

void test_catagory()
{
ProductLinearExp func;
TS_ASSERT_EQUALS("Calibrate", func.category());
}

void test_set_parameters()
{
const double A0 = 1;
const double A1 = 2;
const double Height = 3;
const double Lifetime = 0.1;

ProductLinearExp func;
func.setParameter("A0", A0);
func.setParameter("A1", A1);
func.setParameter("Height", Height);
func.setParameter("Lifetime", Lifetime);

TS_ASSERT_EQUALS(A0, func.getParameter("A0"));
TS_ASSERT_EQUALS(A1, func.getParameter("A1"));
TS_ASSERT_EQUALS(Height, func.getParameter("Height"));
TS_ASSERT_EQUALS(Lifetime, func.getParameter("Lifetime"));
}

void test_execution_with_exp_components_unity()
{
// A1 is set to zero, so the ProductLinearExp function should just reduce to an exp decay function.
const double A0 = 1;
const double A1 = 0;
const double Height = 2;
const double Lifetime = 0.1;

ProductLinearExp func;
func.setParameter("A0", A0);
func.setParameter("A1", A1);
func.setParameter("Height", Height);
func.setParameter("Lifetime", Lifetime);

ExpDecay benchmark;
benchmark.setParameter("Height", Height);
benchmark.setParameter("Lifetime", Lifetime);

const size_t nResults = 10;
typedef std::vector<double> VecDouble;
VecDouble xValues(nResults);
std::generate(xValues.begin(), xValues.end(), LinearIncrementingAssignment(0, 0.1));

FunctionDomain1DVector domain(xValues);
FunctionValues valuesExpDecay(domain);
FunctionValues valuesLinExpDecay(domain);
benchmark.function(domain,valuesExpDecay);
func.function(domain, valuesLinExpDecay);

for(size_t i = 0; i < nResults; ++i)
{
double x = xValues[i];
// Mimic workings of ProductLinearExp function to product comparison output.
double expected = ((A1 * x) + A0)* Height * std::exp(-x/Lifetime);
TS_ASSERT_EQUALS(expected, valuesLinExpDecay[i]);
// As a complete check, verify that the output is also the same for the ExpDecay algorithm.
TS_ASSERT_EQUALS(valuesExpDecay[i], valuesLinExpDecay[i]);
}
}

void test_execution_with_equivalent_composite()
{

const double A0 = 2;
const double A1 = 1;
const double Height = 1;
const double Lifetime = 0;

// Create the Product linear exponential function
ProductLinearExp func;
func.setParameter("A0", A0);
func.setParameter("A1", A1);
func.setParameter("Height", Height);
func.setParameter("Lifetime", Lifetime);

// Create the equivalent Product Function
IFunction_sptr linearFunction = boost::make_shared<LinearBackground>();
linearFunction->initialize();
linearFunction->setParameter("A0", A0);
linearFunction->setParameter("A1", A1);
IFunction_sptr expFunction = boost::make_shared<ExpDecay>();
expFunction->initialize();
expFunction->setParameter("Height", Height);
expFunction->setParameter("Lifetime", Lifetime);
ProductFunction benchmark;
benchmark.initialize();
benchmark.addFunction(linearFunction);
benchmark.addFunction(expFunction);

const size_t nResults = 10;
typedef std::vector<double> VecDouble;
VecDouble xValues(nResults);
std::generate(xValues.begin(), xValues.end(), LinearIncrementingAssignment(0, 0.1));

FunctionDomain1DVector domain(xValues);
FunctionValues valuesLinear(domain);
FunctionValues valuesLinExpDecay(domain);
benchmark.function(domain,valuesLinear);
func.function(domain, valuesLinExpDecay);

for(size_t i = 0; i < nResults; ++i)
{
double x = xValues[i];
// Mimic workings of ProductLinearExp function to product comparison output.
double expected = ((A1 * x) + A0)* Height * std::exp(-x/Lifetime);
TS_ASSERT_EQUALS(expected, valuesLinExpDecay[i]);
// As a complete check, verify that the output is also the same for the Linear algorithm.
//TS_ASSERT_EQUALS(valuesLinear[i], valuesLinExpDecay[i]);
}
}



};


#endif /* MANTID_CURVEFITTING_PRODUCTLINEAREXPTEST_H_ */

0 comments on commit 0b7a4be

Please sign in to comment.