Skip to content

Commit

Permalink
refs #5633. Calculate Jacobian.
Browse files Browse the repository at this point in the history
  • Loading branch information
OwenArnold committed Jul 23, 2012
1 parent 49eb208 commit 60d8b74
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 38 deletions.
25 changes: 20 additions & 5 deletions Code/Mantid/Framework/CurveFitting/src/ProductLinearExp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,30 @@ namespace Mantid

void ProductLinearExp::functionDeriv1D(API::Jacobian* out, const double* xValues, const size_t nData)
{
throw std::runtime_error("Not Implemented");
const double A0 = getParameter("A0");
const double A1 = getParameter("A1");
const double Height = getParameter("Height");
const double Lifetime = getParameter("Lifetime");

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

out->set(i, 0, A1 * x * expComponent );
out->set(i, 1, (x + A0) * expComponent);
out->set(i, 2, linearComponent * expComponent / Height);
out->set(i, 3, linearComponent * expComponent * x / (Lifetime * Lifetime));
}
}

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");
const double A0 = getParameter("A0");
const double A1 = getParameter("A1");
const double Height = getParameter("Height");
const double Lifetime = getParameter("Lifetime");

for(size_t i = 0; i < nData; ++i)
{
Expand Down
64 changes: 31 additions & 33 deletions Code/Mantid/Framework/CurveFitting/test/ProductLinearExpTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,19 @@
#include "MantidCurveFitting/ExpDecay.h"
#include "MantidCurveFitting/LinearBackground.h"
#include "MantidCurveFitting/ProductFunction.h"
#include "MantidAPI/Jacobian.h"
#include "MantidCurveFitting/Jacobian.h"
#include "MantidAPI/FunctionDomain1D.h"
#include "MantidAPI/FunctionValues.h"
#include <algorithm>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <gmock/gmock.h>

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

class ProductLinearExpTest : public CxxTest::TestSuite
{
private:

/// Mock helper type.
class MockJacobian : public Mantid::API::Jacobian
{
public:
MOCK_METHOD3(set, void(size_t, size_t, double));
MOCK_METHOD2(get, double(size_t, size_t));
~MockJacobian()
{
}
};

/// Helper type to generate number for a std::generate call.
class LinearIncrementingAssignment
Expand Down Expand Up @@ -84,13 +72,19 @@ class ProductLinearExpTest : public CxxTest::TestSuite
const size_t nResults = 10;
typedef std::vector<double> VecDouble;
VecDouble xValues(nResults);
std::generate(xValues.begin(), xValues.end(), LinearIncrementingAssignment(0, 0.1));
std::generate(xValues.begin(), xValues.end(), LinearIncrementingAssignment(0, 0.0001));

FunctionDomain1DVector domain(xValues);
FunctionValues valuesLinear(domain);
FunctionValues valuesBenchmark(domain);
FunctionValues valuesLinExpDecay(domain);
benchmark.function(domain,valuesLinear);
Mantid::CurveFitting::Jacobian jacobianNumerical(nResults, 4);
Mantid::CurveFitting::Jacobian jacobianLinExpDecay(nResults, 4);
// Peform function evaluations.
benchmark.function(domain, valuesBenchmark);
func.function(domain, valuesLinExpDecay);
// Perform function derivative evaluations.
func.functionDeriv(domain, jacobianLinExpDecay);
func.calNumericalDeriv(domain, jacobianNumerical);

for(size_t i = 0; i < nResults; ++i)
{
Expand All @@ -99,8 +93,12 @@ class ProductLinearExpTest : public CxxTest::TestSuite
double expected = ((A1 * x) + A0)* Height * std::exp(-x/Lifetime);
TS_ASSERT_DELTA(expected, valuesLinExpDecay[i], 0.0001);

// As a complete check, verify that the output is also the same for the Linear algorithm.
TS_ASSERT_DELTA(valuesLinear[i], valuesLinExpDecay[i], 0.0001);
// Verify that the output is also the same for the Linear algorithm.
TS_ASSERT_DELTA(valuesBenchmark[i], valuesLinExpDecay[i], 0.0001);

// Verify that the derivates calculated are also the same.
TS_ASSERT_DELTA(jacobianLinExpDecay.get(i, 2), jacobianNumerical.get(i, 2), 0.1); // w.r.t Height
TS_ASSERT_DELTA(jacobianLinExpDecay.get(i, 3), jacobianNumerical.get(i, 3), 0.1); // w.r.t Lifetime
}
}

Expand Down Expand Up @@ -181,42 +179,42 @@ class ProductLinearExpTest : public CxxTest::TestSuite
}
}

void test_calculate_derivative_throws()
void test_calculate_derivative_throws_nothing()
{
// NOT implemented. Characterise with test.
ProductLinearExp func;

FunctionDomain1DVector domain(0);
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);

MockJacobian jacobian;
Mantid::CurveFitting::Jacobian jacobian(nResults, 4);

TS_ASSERT_THROWS(func.functionDeriv(domain, jacobian), std::runtime_error);
ProductLinearExp func;
TS_ASSERT_THROWS_NOTHING(func.functionDeriv(domain, jacobian));
}

void test_with_low_contribution_from_expdecay()
{
// Setup the test to for low contribution from exponential component.
const double A0 = 2;
const double A1 = 1;
const double A0 = 0.2;
const double A1 = 0.1;
const double Height = 1;
const double Lifetime = 1000000;
const double Lifetime = 100;

do_test_function_calculation(A0, A1, Height, Lifetime);
}

void test_with_high_contribution_from_expdecay()
{
// Setup the test to for high contribution from exponential component.
const double A0 = 2;
const double A1 = 1;
const double A0 = 0.2;;
const double A1 = 0.1;
const double Height = 1;
const double Lifetime = 0.000001;
const double Lifetime = 0.01;

do_test_function_calculation(A0, A1, Height, Lifetime);
}



};


Expand Down

0 comments on commit 60d8b74

Please sign in to comment.