Skip to content

Commit

Permalink
Re #4158. Added FitMW algorithm.
Browse files Browse the repository at this point in the history
  • Loading branch information
mantid-roman committed Apr 2, 2012
1 parent e8c2d03 commit 5dbc09a
Show file tree
Hide file tree
Showing 54 changed files with 2,305 additions and 822 deletions.
9 changes: 9 additions & 0 deletions Code/Mantid/Framework/API/inc/MantidAPI/CompositeFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ class MANTID_API_DLL CompositeFunction : public virtual IFunction
std::string parameterDescription(size_t i)const;
/// Checks if a parameter has been set explicitly
bool isExplicitlySet(size_t i)const;
/// Get the fitting error for a parameter
virtual double getError(size_t i) const;
/// Set the fitting error for a parameter
virtual void setError(size_t i, double err);

/// Check if a parameter is active
bool isFixed(size_t i)const;
Expand All @@ -103,6 +107,11 @@ class MANTID_API_DLL CompositeFunction : public virtual IFunction
std::string descriptionOfActive(size_t i)const;
/// Check if an active parameter i is actually active
bool isActive(size_t i)const;
/// Return the transformation matrix T between parameters such that p_i = T_ij * ap_j,
/// where ap_j is j-th active parameter.
virtual void getTransformationMatrix(Kernel::Matrix<double>& tm);
/// Is the transformation an identity?
virtual bool isTransformationIdentity() const;

/// Return parameter index from a parameter reference.
size_t getParameterIndex(const ParameterReference& ref)const;
Expand Down
2 changes: 2 additions & 0 deletions Code/Mantid/Framework/API/inc/MantidAPI/FunctionDomain1D.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ namespace API
class MANTID_API_DLL FunctionDomain1D: public FunctionDomain
{
public:
FunctionDomain1D(const double startX, const double endX, const size_t n);
FunctionDomain1D(const std::vector<double>& xvalues);
FunctionDomain1D(std::vector<double>::const_iterator from, std::vector<double>::const_iterator to);
/// Return the number of arguments in the domain
virtual size_t size() const {return m_X.size();}
/// Get an x value.
Expand Down
2 changes: 2 additions & 0 deletions Code/Mantid/Framework/API/inc/MantidAPI/FunctionValues.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ class MANTID_API_DLL FunctionValues
double* getPointerToCalculated(size_t i);
/// Add other calculated values
FunctionValues& operator+=(const FunctionValues& values);
/// Set all calculated values to zero
void zeroCalculated();

/// set a fitting data value
void setFitData(size_t i,double value);
Expand Down
12 changes: 12 additions & 0 deletions Code/Mantid/Framework/API/inc/MantidAPI/IFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "MantidAPI/FunctionDomain.h"
#include "MantidAPI/FunctionValues.h"
#include "MantidAPI/Jacobian.h"
#include "MantidKernel/Matrix.h"
#include "MantidKernel/Logger.h"
#include "MantidKernel/Exception.h"
#include <boost/shared_ptr.hpp>
Expand Down Expand Up @@ -275,6 +276,10 @@ class MANTID_API_DLL IFunction
virtual std::string parameterDescription(size_t i)const = 0;
/// Checks if a parameter has been set explicitly
virtual bool isExplicitlySet(size_t i)const = 0;
/// Get the fitting error for a parameter
virtual double getError(size_t i) const = 0;
/// Set the fitting error for a parameter
virtual void setError(size_t i, double err) = 0;

/// Check if a declared parameter i is fixed
virtual bool isFixed(size_t i)const = 0;
Expand All @@ -299,6 +304,11 @@ class MANTID_API_DLL IFunction
virtual std::string descriptionOfActive(size_t i)const;
/// Check if an active parameter i is actually active
virtual bool isActive(size_t i)const {return !isFixed(i);}
/// Return the transformation matrix T between parameters such that p_i = T_ij * ap_j,
/// where ap_j is j-th active parameter.
virtual void getTransformationMatrix(Kernel::Matrix<double>& tm);
/// Is the transformation an identity?
virtual bool isTransformationIdentity() const {return true;}
//@}


Expand Down Expand Up @@ -366,6 +376,8 @@ class MANTID_API_DLL IFunction

/// Calculate numerical derivatives
void calNumericalDeriv(const FunctionDomain& domain, Jacobian& out);
/// Calculate the transformation matrix T by numeric differentiation
void calTransformationMatrixNumerically(Kernel::Matrix<double>& tm);

/// Create an instance of a tie without actually tying it to anything
//virtual ParameterTie* createTie(const std::string& parName);
Expand Down
6 changes: 4 additions & 2 deletions Code/Mantid/Framework/API/inc/MantidAPI/IFunction1D.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,13 @@ class MANTID_API_DLL IFunction1D: public virtual IFunction
virtual void function(const FunctionDomain& domain,FunctionValues& values)const;
void functionDeriv(const FunctionDomain& domain, Jacobian& jacobian);

protected:

/// Function you want to fit to.
virtual void function1D(double* out, const double* xValues, const size_t nData)const = 0;
/// Derivatives of function with respect to active parameters
virtual void functionDeriv1D(Jacobian* out, const double* xValues, const size_t nData);

protected:

/// Static reference to the logger class
static Kernel::Logger& g_log;

Expand All @@ -132,6 +132,8 @@ class MANTID_API_DLL IFunction1D: public virtual IFunction

};

typedef boost::shared_ptr<IFunction1D> IFunction1D_sptr;

} // namespace API
} // namespace Mantid

Expand Down
6 changes: 6 additions & 0 deletions Code/Mantid/Framework/API/inc/MantidAPI/ParamFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ class MANTID_API_DLL ParamFunction : public virtual IFunction
virtual std::string parameterDescription(size_t i)const;
/// Checks if a parameter has been set explicitly
virtual bool isExplicitlySet(size_t i)const;
/// Get the fitting error for a parameter
virtual double getError(size_t i) const;
/// Set the fitting error for a parameter
virtual void setError(size_t i, double err);

/// Check if a declared parameter i is active
virtual bool isFixed(size_t i)const;
Expand Down Expand Up @@ -149,6 +153,8 @@ class MANTID_API_DLL ParamFunction : public virtual IFunction
std::vector<std::string> m_parameterNames;
/// Keeps parameter values
std::vector<double> m_parameters;
/// Keeps parameter errors
std::vector<double> m_errors;
/// Holds parameter ties as <parameter index,tie pointer>
std::vector<ParameterTie*> m_ties;
/// Holds the constraints added to function
Expand Down
68 changes: 68 additions & 0 deletions Code/Mantid/Framework/API/src/CompositeFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ std::string CompositeFunction::asString()const
void CompositeFunction::function(const FunctionDomain& domain, FunctionValues& values)const
{
FunctionValues tmp(domain);
values.zeroCalculated();
for(size_t iFun = 0; iFun < nFunctions(); ++iFun)
{
domain.reset();
Expand Down Expand Up @@ -258,6 +259,28 @@ std::string CompositeFunction::parameterDescription(size_t i)const
return ostr.str();
}

/**
* Get the fitting error for a parameter
* @param i :: The index of a parameter
* @return :: the error
*/
double CompositeFunction::getError(size_t i) const
{
size_t iFun = functionIndex(i);
return m_functions[ iFun ]->getError(i - m_paramOffsets[iFun]);
}

/**
* Set the fitting error for a parameter
* @param i :: The index of a parameter
* @param err :: The error value to set
*/
void CompositeFunction::setError(size_t i, double err)
{
size_t iFun = functionIndex(i);
m_functions[ iFun ]->setError(i - m_paramOffsets[iFun], err);
}

/// Value of i-th active parameter. Override this method to make fitted parameters different from the declared
double CompositeFunction::activeParameter(size_t i)const
{
Expand Down Expand Up @@ -837,5 +860,50 @@ IFunction_sptr CompositeFunction::getContainingFunction(const ParameterReference
// return IFunction_sptr();
//}

/// Is the transformation an identity?
bool CompositeFunction::isTransformationIdentity() const
{
for(size_t iFun = 0; iFun < nFunctions(); ++iFun)
{
if ( !getFunction(iFun)->isTransformationIdentity() )
{
return false;
}
}
return true;
}

/**
* Return the transformation matrix T between parameters such that p_i = T_ij * ap_j,
* where ap_j is j-th active parameter.
* @param tm :: The output matrix
*/
void CompositeFunction::getTransformationMatrix(Kernel::Matrix<double>& tm)
{
size_t np = nParams();
tm.setMem(np, np);
tm.identityMatrix();
if ( this->isTransformationIdentity() ) return;
for(size_t iFun = 0; iFun < nFunctions(); ++iFun)
{
IFunction_sptr f = getFunction(iFun);
if ( !f->isTransformationIdentity() )
{
size_t i0 = m_paramOffsets[iFun];
size_t np1 = f->nParams();
Kernel::Matrix<double> tm1(np1,np1);
f->getTransformationMatrix(tm1);
for(size_t i = 0; i < np1; ++i)
{
for(size_t j = 0; j < np1; ++j)
{
tm[i0 + i][i0 + j] = tm1[i][j];
}
}
} // !identity
}
}


} // namespace API
} // namespace Mantid
29 changes: 29 additions & 0 deletions Code/Mantid/Framework/API/src/FunctionDomain1D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,35 @@ FunctionDomain1D::FunctionDomain1D(const std::vector<double>& xvalues)
m_X.assign(xvalues.begin(),xvalues.end());
}

FunctionDomain1D::FunctionDomain1D(std::vector<double>::const_iterator from, std::vector<double>::const_iterator to)
{
if (from == to)
{
throw std::invalid_argument("FunctionDomain1D cannot have zero size.");
}
m_X.assign(from,to);
}

FunctionDomain1D::FunctionDomain1D(const double startX, const double endX, const size_t n)
{
if (n == 0)
{
throw std::invalid_argument("FunctionDomain1D cannot have zero size.");
}
m_X.resize(n);
if (n == 1)
{
m_X[0] = (startX + endX) / 2;
}
else
{
const double dx = (endX - startX) / (n - 1);
for(size_t i = 0; i < n; ++i)
{
m_X[i] = startX + dx * i;
}
}
}

} // namespace API
} // namespace Mantid
7 changes: 7 additions & 0 deletions Code/Mantid/Framework/API/src/FunctionValues.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ namespace API
return *this;
}

/// Set all calculated values to zero
void FunctionValues::zeroCalculated()
{
std::fill(m_calculated.begin(),m_calculated.end(),0.0);
}


/**
* Set a fitting data value.
* @param i :: Index
Expand Down
64 changes: 63 additions & 1 deletion Code/Mantid/Framework/API/src/IFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include <Poco/StringTokenizer.h>

#include <limits>
#include <sstream>
#include <iostream>

Expand Down Expand Up @@ -457,7 +458,7 @@ std::string IFunction::descriptionOfActive(size_t i)const
void IFunction::calNumericalDeriv(const FunctionDomain& domain, Jacobian& jacobian)
{
const double minDouble = std::numeric_limits<double>::min();
const double epsilon = std::numeric_limits<double>::epsilon();
const double epsilon = std::numeric_limits<double>::epsilon() * 100;
double stepPercentage = 0.001; // step percentage
double step; // real step
double cutoff = 100.0*minDouble/stepPercentage;
Expand Down Expand Up @@ -502,5 +503,66 @@ void IFunction::calNumericalDeriv(const FunctionDomain& domain, Jacobian& jacobi
}
}

/**
* Return the transformation matrix T between parameters such that p_i = T_ij * ap_j,
* where ap_j is j-th active parameter.
* @param tm :: The output matrix
*/
void IFunction::getTransformationMatrix(Kernel::Matrix<double>& tm)
{
size_t np = nParams();
tm.setMem(np, np);
tm.identityMatrix();
}

/**
* Calculate the transformation matrix T by numeric differentiation
* @param tm :: The output transformation matrix.
*/
void IFunction::calTransformationMatrixNumerically(Kernel::Matrix<double>& tm)
{
double epsilon = std::numeric_limits<double>::epsilon() * 100;
size_t np = nParams();
tm.setMem(np,np);
for(size_t i = 0; i < np; ++i)
{
double p0 = getParameter(i);
for(size_t j = 0; j < np; ++j)
{
double ap = activeParameter(j);
double step = ap == 0.0? epsilon : ap * epsilon;
setActiveParameter( j, ap + step );
tm[i][j] = ( getParameter(i) - p0 ) / step;
setActiveParameter( j, ap );
}
}
}

} // namespace API
} // namespace Mantid

///\cond TEMPLATE
namespace Mantid
{
namespace Kernel
{

template<> MANTID_API_DLL
boost::shared_ptr<Mantid::API::IFunction> IPropertyManager::getValue<boost::shared_ptr<Mantid::API::IFunction> >(const std::string &name) const
{
PropertyWithValue<boost::shared_ptr<Mantid::API::IFunction> >* prop =
dynamic_cast<PropertyWithValue<boost::shared_ptr<Mantid::API::IFunction> >*>(getPointerToProperty(name));
if (prop)
{
return *prop;
}
else
{
std::string message = "Attempt to assign property "+ name +" to incorrect type. Expected IFitFunction.";
throw std::runtime_error(message);
}
}

} // namespace Kernel
} // namespace Mantid
///\endcond TEMPLATE
30 changes: 30 additions & 0 deletions Code/Mantid/Framework/API/src/ParamFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,35 @@ std::string ParamFunction::parameterDescription(size_t i)const
return m_parameterDescriptions[i];
}

/**
* Get the fitting error for a parameter
* @param i :: The index of a parameter
* @return :: the error
*/
double ParamFunction::getError(size_t i) const
{
if (i >= nParams())
{
throw std::out_of_range("ParamFunction parameter index out of range.");
}
return m_errors[i];
}

/**
* Set the fitting error for a parameter
* @param i :: The index of a parameter
* @param err :: The error value to set
*/
void ParamFunction::setError(size_t i, double err)
{
if (i >= nParams())
{
throw std::out_of_range("ParamFunction parameter index out of range.");
}
m_errors[i] = err;
}


/**
* Declare a new parameter. To used in the implementation'c constructor.
* @param name :: The parameter name.
Expand All @@ -227,6 +256,7 @@ void ParamFunction::declareParameter(const std::string& name,double initValue, c
m_parameterNames.push_back(ucName);
m_parameterDescriptions.push_back(description);
m_parameters.push_back(initValue);
m_errors.push_back(0.0);
m_explicitlySet.push_back(false);
}

Expand Down

0 comments on commit 5dbc09a

Please sign in to comment.