Skip to content

Commit

Permalink
Re #4158. Started refactoring functions
Browse files Browse the repository at this point in the history
  • Loading branch information
mantid-roman committed Apr 2, 2012
1 parent b06a486 commit 125eb67
Show file tree
Hide file tree
Showing 13 changed files with 663 additions and 509 deletions.
5 changes: 5 additions & 0 deletions Code/Mantid/Framework/API/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ set ( SRC_FILES
src/FileProperty.cpp
src/FrameworkManager.cpp
src/FunctionDomain.cpp
src/FunctionDomain1D.cpp
src/FunctionFactory.cpp
src/FunctionProperty.cpp
src/IDataFileChecker.cpp
Expand All @@ -36,6 +37,7 @@ set ( SRC_FILES
src/IFitFunction.cpp
src/IFunction.cpp
src/IFunctionMD.cpp
src/IFunction1D.cpp
src/IFunctionMW.cpp
src/ILiveListener.cpp
src/IMDEventWorkspace.cpp
Expand Down Expand Up @@ -128,6 +130,7 @@ set ( INC_FILES
inc/MantidAPI/FileProperty.h
inc/MantidAPI/FrameworkManager.h
inc/MantidAPI/FunctionDomain.h
inc/MantidAPI/FunctionDomain1D.h
inc/MantidAPI/FunctionFactory.h
inc/MantidAPI/FunctionProperty.h
inc/MantidAPI/IAlgorithm.h
Expand All @@ -143,6 +146,7 @@ set ( INC_FILES
inc/MantidAPI/IFitFunction.h
inc/MantidAPI/IFunction.h
inc/MantidAPI/IFunctionMD.h
inc/MantidAPI/IFunction1D.h
inc/MantidAPI/IFunctionMW.h
inc/MantidAPI/IFunctionWithLocation.h
inc/MantidAPI/ILiveListener.h
Expand Down Expand Up @@ -230,6 +234,7 @@ set ( TEST_FILES
test/FunctionPropertyTest.h
test/FunctionTest.h
test/IEventListTest.h
test/IFunction1DTest.h
test/IFunctionMDTest.h
test/ILiveListenerTest.h
test/IMDWorkspaceTest.h
Expand Down
58 changes: 58 additions & 0 deletions Code/Mantid/Framework/API/inc/MantidAPI/FunctionDomain1D.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#ifndef MANTID_API_FUNCTIONDOMAIN1D_H_
#define MANTID_API_FUNCTIONDOMAIN1D_H_

//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAPI/FunctionDomain.h"

#include <vector>

namespace Mantid
{
namespace API
{
/** Base class that represents the domain of a function.
A domain is a generalisation of x (argument) and y (value) arrays.
A domain consists at least of a list of function arguments for which a function should
be evaluated and a buffer for the calculated values. If used in fitting also contains
the fit data and weights.
@author Roman Tolchenov, Tessella plc
@date 15/11/2011
Copyright &copy; 2009 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 MANTID_API_DLL FunctionDomain1D: public FunctionDomain
{
public:
FunctionDomain1D(const std::vector<double>& xvalues);
/// get an x value
/// @param i :: Index
double getX(size_t i) const {return m_X.at(i);}
protected:
std::vector<double> m_X; ///< vector of function arguments
};

} // namespace API
} // namespace Mantid

#endif /*MANTID_API_FUNCTIONDOMAIN1D_H_*/
10 changes: 10 additions & 0 deletions Code/Mantid/Framework/API/inc/MantidAPI/FunctionFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,14 @@ namespace API
} // namespace API
} // namespace Mantid

/**
* Macro for declaring a new type of function to be used with the FunctionFactory
*/
#define DECLARE_FUNCTION(classname) \
namespace { \
Mantid::Kernel::RegistrationHelper register_function_##classname( \
((Mantid::API::FunctionFactory::Instance().subscribe<classname>(#classname)) \
, 0)); \
}

#endif /*MANTID_API_FUNCTIONFACTORY_H_*/
21 changes: 10 additions & 11 deletions Code/Mantid/Framework/API/inc/MantidAPI/IFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ class MANTID_API_DLL IFunction
virtual std::string asString()const;
/// Set the workspace. Make
/// @param ws :: Shared pointer to a workspace
virtual void setWorkspace(boost::shared_ptr<const Workspace> ws) = 0;
virtual void setWorkspace(boost::shared_ptr<const Workspace> ws) {}
/// Get the workspace
//virtual boost::shared_ptr<const API::Workspace> getWorkspace()const = 0;
/// Iinialize the function
Expand Down Expand Up @@ -276,26 +276,22 @@ class MANTID_API_DLL IFunction
/// Number of active (in terms of fitting) parameters
virtual size_t nActive()const = 0;
/// Value of i-th active parameter. Override this method to make fitted parameters different from the declared
virtual double activeParameter(size_t i)const;
virtual double activeParameter(size_t i)const = 0;
/// Set new value of i-th active parameter. Override this method to make fitted parameters different from the declared
virtual void setActiveParameter(size_t i, double value);
/// Update parameters after a fitting iteration
virtual void updateActive(const double* in);
/// Returns "global" index of active parameter i
virtual size_t indexOfActive(size_t i)const = 0;
virtual void setActiveParameter(size_t i, double value) = 0;
/// Returns the name of active parameter i
virtual std::string nameOfActive(size_t i)const = 0;
/// Returns the name of active parameter i
virtual std::string descriptionOfActive(size_t i)const = 0;

/// Check if a declared parameter i is active
virtual bool isActive(size_t i)const = 0;
virtual bool isFixed(size_t i)const = 0;
/// Get active index for a declared parameter i
virtual size_t activeIndex(size_t i)const = 0;
//virtual size_t activeIndex(size_t i)const = 0;
/// Removes a declared parameter i from the list of active
virtual void removeActive(size_t i) = 0;
virtual void fix(size_t i) = 0;
/// Restores a declared parameter i to the active status
virtual void restoreActive(size_t i) = 0;
virtual void unfix(size_t i) = 0;

/// Return parameter index from a parameter reference. Usefull for constraints and ties in composite functions
virtual size_t getParameterIndex(const ParameterReference& ref)const = 0;
Expand Down Expand Up @@ -368,6 +364,9 @@ class MANTID_API_DLL IFunction
/// Declare a new parameter
virtual void declareParameter(const std::string& name, double initValue = 0, const std::string& description="") = 0;

//virtual size_t indexOfActive(size_t i)const = 0;
//virtual size_t activeIndex(size_t i)const = 0;

/// Create an instance of a tie without actually tying it to anything
virtual ParameterTie* createTie(const std::string& parName);
/// Add a new tie
Expand Down
153 changes: 153 additions & 0 deletions Code/Mantid/Framework/API/inc/MantidAPI/IFunction1D.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
#ifndef MANTID_API_IFUNCTION1D_H_
#define MANTID_API_IFUNCTION1D_H_

//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAPI/DllConfig.h"
#include "MantidAPI/IFunction.h"
#include "MantidAPI/FunctionDomain1D.h"

namespace Mantid
{

namespace CurveFitting
{
class Fit;
}

namespace API
{

//----------------------------------------------------------------------
// Forward declaration
//----------------------------------------------------------------------
class MatrixWorkspace;
class Jacobian;
class ParameterTie;
class IConstraint;
class ParameterReference;
class FunctionHandler;
/** This is an interface to a fitting function - a semi-abstarct class.
Functions derived from IFunctionMW can be used with the Fit algorithm.
IFunctionMW defines the structure of a fitting funtion.
A function has a number of named parameters (not arguments), type double, on which it depends.
Parameters must be declared either in the constructor or in the init() method
of a derived class with method declareParameter(...). Method nParams() returns
the number of declared parameters. A parameter can be accessed either by its name
or the index. For example in case of Gaussian the parameters can be "Height",
"PeakCentre" and "Sigma".
To fit a function to a set of data its parameters must be adjusted so that the difference
between the data and the corresponding function values were minimized. This is the aim
of the Fit algorithm. But Fit does not work with the declared parameters directly.
Instead it uses other - active - parameters. The active parameters can be a subset of the
declared parameters or completely different ones. The rationale for this is following.
The fitting parameters sometimes need to be fixed during the fit or "tied" (expressed
in terms of other parameters). In this case the active parameters will be those
declared parameters which are not tied in any sence. Also some of the declared parameters
can be unsuitable for the use in a fitting algorithm. In this case different active parameters
can be used in place of the inefficient declared parameters. An example is Gaussian where
"Sigma" makes the fit unstable. So in the fit it can be replaced with variable Weight = 1 / Sigma
which is more efficient. The number of active parameters (returned by nActive()) cannot be
greater than nParams(). The function which connects the active parameters with the declared ones
must be monotonic so that the forward and backward transformations between the two sets are
single-valued (this is my understanding). At the moment only simple one to one transformations
of Weight - Sigma type are allowed. More complecated cases of simultaneous transformations of
several parameters are not supported.
The active parameters can be accessed by their index. The implementations of the access method
for both active and declared parameters must ensure that any changes to one of them
immediately reflected on the other so that the two are consistent at any moment.
IFunctionMW declares method nameOfActive(size_t i) which returns the name of the declared parameter
corresponding to the i-th active parameter. I am not completely sure in the usefulness of it.
IFunctionMW provides methods for tying and untying parameters. Only the declared parameters can be
tied. A tied parameter cannot be active. When a parameter is tied it becomes inactive.
This implies that the number of active parameters is variable and can change at runtime.
Method addConstraint adds constraints on possible values of a declared parameter. Constraints
and ties are used only in fitting.
The main method of IFunctionMW is called function(out,xValues,nData). It calculates nData output values
out[i] at arguments xValues[i]. Implement functionDeriv method for the function to be used with
fitting algorithms using derivatives. functionDeriv calculates patrial derivatives of the
function with respect to the fitting parameters.
Any non-fitting parameters can be implemented as attributes (class IFunctionMW::Attribute).
An attribute can have one of three types: std::string, int, or double. The type is set at construction
and cannot be changed later. To read or write the attributes there are two ways. If the type
is known the type specific accessors can be used, e.g. asString(), asInt(). Otherwise the
IFunctionMW::AttributeVisitor can be used. It provides alternative virtual methods to access
attributes of each type. When creating a function from a string (using FunctionFactory::creaeInitialized(...))
the attributes must be set first, before any fitting parameter, as the number and names of the parameters
can depend on the attributes.
@author Roman Tolchenov, Tessella Support Services plc
@date 16/10/2009
Copyright &copy; 2009 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 MANTID_API_DLL IFunction1D: public virtual IFunction
{
public:

/// Constructor
IFunction1D():IFunction(){}

/* Overidden methods */

virtual void function(FunctionDomain& )const;
void functionDeriv(FunctionDomain& domain, Jacobian& jacobian);

//boost::shared_ptr<API::MatrixWorkspace> createCalculatedWorkspace(
// boost::shared_ptr<const API::MatrixWorkspace> inWS,
// size_t wi,
// const std::vector<double>& sd = std::vector<double>()
// );

protected:

/// Function you want to fit to.
virtual void function1D(FunctionDomain1D&)const = 0;
/// Derivatives of function with respect to active parameters
virtual void functionDeriv1D(FunctionDomain1D&, Jacobian& out);

/// Calculate numerical derivatives
void calNumericalDeriv(FunctionDomain1D& domain, Jacobian& out);

mutable std::vector<double> m_tmpFunctionOutputMinusStep;
mutable std::vector<double> m_tmpFunctionOutputPlusStep;

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

/// Making a friend
friend class CurveFitting::Fit;

};

} // namespace API
} // namespace Mantid

#endif /*MANTID_API_IFUNCTION1D_H_*/

0 comments on commit 125eb67

Please sign in to comment.