Newer
Older
Roman Tolchenov
committed
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAPI/IPeakFunction.h"
#include "MantidKernel/Exception.h"
Roman Tolchenov
committed
#include "MantidKernel/ConfigService.h"
Roman Tolchenov
committed
Roman Tolchenov
committed
#include <boost/lexical_cast.hpp>
Roman Tolchenov
committed
#include <cmath>
namespace Mantid
{
namespace API
{
/** A Jacobian for individual functions
*/
class PartialJacobian1: public Jacobian
{
Jacobian* m_J; ///< pointer to the overall Jacobian
int m_iY0; ///< offset in the overall Jacobian for a particular function
public:
/** Constructor
Janik Zikovsky
committed
* @param J :: A pointer to the overall Jacobian
* @param iY0 :: The data offset for a particular function
Roman Tolchenov
committed
*/
PartialJacobian1(Jacobian* J,int iY0):m_J(J),m_iY0(iY0)
{}
/**
* Overridden Jacobian::set(...).
Janik Zikovsky
committed
* @param iY :: The index of the data point
* @param iP :: The parameter index of an individual function.
* @param value :: The derivative value
Roman Tolchenov
committed
*/
void set(int iY, int iP, double value)
{
m_J->set(m_iY0 + iY,iP,value);
}
};
Roman Tolchenov
committed
/// Default value for the peak radius
Roman Tolchenov
committed
int IPeakFunction::s_peakRadius = 5;
Roman Tolchenov
committed
/**
* Constructor. Sets peak radius to the value of curvefitting.peakRadius property
*/
IPeakFunction::IPeakFunction()
{
int peakRadius;
if ( Kernel::ConfigService::Instance().getValue("curvefitting.peakRadius",peakRadius) )
{
setPeakRadius(peakRadius);
}
}
Roman Tolchenov
committed
/**
* General implementation of the method for all peaks. Limits the peak evaluation to
* a certain number of FWHMs around the peak centre. The outside points are set to 0.
* Calls functionLocal() to compute the actual values
Janik Zikovsky
committed
* @param out :: Output function values
* @param xValues :: X values for data points
* @param nData :: Number of data points
Roman Tolchenov
committed
*/
void IPeakFunction::function(double* out, const double* xValues, const int& nData)const
{
double c = this->centre();
double dx = fabs(s_peakRadius*this->width());
int i0 = -1;
int n = 0;
for(int i = 0; i < nData; ++i)
{
if (fabs(xValues[i] - c) < dx)
{
if (i0 < 0) i0 = i;
++n;
}
else
{
out[i] = 0.;
}
}
if (i0 < 0 || n == 0) return;
this->functionLocal(out+i0,xValues+i0,n);
}
/**
* General implementation of the method for all peaks. Calculates derivatives only
* for a range of x values limited to a certain number of FWHM around the peak centre.
* For the points outside the range all derivatives are set to 0.
* Calls functionDerivLocal() to compute the actual values
Janik Zikovsky
committed
* @param out :: Derivatives
* @param xValues :: X values for data points
* @param nData :: Number of data points
Roman Tolchenov
committed
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
*/
void IPeakFunction::functionDeriv(Jacobian* out, const double* xValues, const int& nData)
{
double c = this->centre();
double dx = fabs(s_peakRadius*this->width());
int i0 = -1;
int n = 0;
for(int i = 0; i < nData; ++i)
{
if (fabs(xValues[i] - c) < dx)
{
if (i0 < 0) i0 = i;
++n;
}
else
{
for(int ip = 0; ip < this->nParams(); ++ip)
{
out->set(i,ip, 0.0);
}
}
}
if (i0 < 0 || n == 0) return;
PartialJacobian1 J(out,i0);
this->functionDerivLocal(&J,xValues+i0,n);
}
void IPeakFunction::setPeakRadius(const int& r)
{
if (r > 0)
{
s_peakRadius = r;
Roman Tolchenov
committed
std::string setting = boost::lexical_cast<std::string>(r);
Kernel::ConfigService::Instance().setString("curvefitting.peakRadius",setting);
Roman Tolchenov
committed
}
}
} // namespace API
} // namespace Mantid