Commit 8610c6ed authored by Roman Tolchenov's avatar Roman Tolchenov
Browse files

Another bit of changes to the functions class structure. re #2132

parent 42ab1bc6
......@@ -11,18 +11,18 @@ set ( SRC_FILES src/Algorithm.cpp
src/Column.cpp
src/ColumnFactory.cpp
src/CompositeFunction.cpp
#src/CompositeFunctionMW.cpp
src/CompositeFunctionMW.cpp
src/ConstraintFactory.cpp
src/Expression.cpp
src/FileFinder.cpp
src/FileProperty.cpp
src/FrameworkManager.cpp
src/Function.cpp
#src/Function.cpp
src/FunctionFactory.cpp
src/IDataFileChecker.cpp
src/IEventWorkspace.cpp
src/IFitFunction.cpp
src/IFunction.cpp
#src/IFunction.cpp
src/IFunctionMW.cpp
src/IFunctionMD.cpp
src/IMDWorkspace.cpp
......@@ -75,7 +75,7 @@ set ( INC_FILES inc/MantidAPI/AlgorithmFactory.h
inc/MantidAPI/ColumnFactory.h
inc/MantidAPI/Column.h
inc/MantidAPI/CompositeFunction.h
#inc/MantidAPI/CompositeFunctionMW.h
inc/MantidAPI/CompositeFunctionMW.h
inc/MantidAPI/ConstraintFactory.h
inc/MantidAPI/DeclareUserAlg.h
inc/MantidAPI/DllExport.h
......@@ -84,7 +84,7 @@ set ( INC_FILES inc/MantidAPI/AlgorithmFactory.h
inc/MantidAPI/FileProperty.h
inc/MantidAPI/FrameworkManager.h
inc/MantidAPI/FunctionFactory.h
inc/MantidAPI/Function.h
#inc/MantidAPI/Function.h
inc/MantidAPI/IAlgorithm.h
inc/MantidAPI/IArchiveSearch.h
inc/MantidAPI/IBackgroundFunction.h
......@@ -94,7 +94,7 @@ set ( INC_FILES inc/MantidAPI/AlgorithmFactory.h
inc/MantidAPI/IDataItem.h
inc/MantidAPI/IEventWorkspace.h
inc/MantidAPI/IFitFunction.h
inc/MantidAPI/IFunction.h
#inc/MantidAPI/IFunction.h
inc/MantidAPI/IFunctionMW.h
inc/MantidAPI/IFunctionMD.h
inc/MantidAPI/IFunctionWithLocation.h
......@@ -158,6 +158,7 @@ set ( TEST_FILES test/AlgorithmHistoryTest.h
test/FilePropertyTest.h
test/FrameworkManagerTest.h
test/FunctionTest.h
test/IFunctionMDTest.h
test/IMDWorkspaceTest.h
test/ImplicitFunctionParserFactoryTest.h
test/InstrumentDataServiceTest.h
......
......@@ -4,12 +4,14 @@
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAPI/IFunction.h"
#include "MantidAPI/IFitFunction.h"
#include <boost/shared_array.hpp>
namespace Mantid
{
namespace API
{
class MatrixWorkspace;
/** A composite function.
@author Roman Tolchenov, Tessella Support Services plc
......@@ -35,7 +37,7 @@ namespace API
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 CompositeFunction : public IFunction
class DLLExport CompositeFunction : public virtual IFitFunction
{
public:
/// Default constructor
......@@ -49,21 +51,12 @@ public:
/* Overriden methods */
void setWorkspace(boost::shared_ptr<Workspace> ws,const std::string& slicing);
/// Set the workspace
void setMatrixWorkspace(boost::shared_ptr<const API::MatrixWorkspace> workspace,int spec,int xMin,int xMax);
//void setWorkspace(boost::shared_ptr<Workspace> ws,const std::string& slicing);
/// Returns the function's name
std::string name()const{return "CompositeFunction";}
//std::string name()const{return "CompositeFunction";}
/// Writes itself into a string
std::string asString()const;
/// Function you want to fit to.
void function(double* out, const double* xValues, const int& nData)const;
/// Derivatives of function with respect to active parameters
void functionDeriv(Jacobian* out, const double* xValues, const int& nData);
/// Derivatives to be used in covariance matrix calculation.
void calJacobianForCovariance(Jacobian* out, const double* xValues, const int& nData);
/// Set i-th parameter
void setParameter(int, const double& value, bool explicitlySet = true);
/// Get i-th parameter
......@@ -121,7 +114,7 @@ public:
/// Get the tie of i-th parameter
ParameterTie* getTie(int i)const;
/// Overwrite IFunction methods
/// Overwrite IFitFunction methods
void addConstraint(IConstraint* ic);
/// Get constraint of i-th parameter
virtual IConstraint* getConstraint(int i)const;
......@@ -129,20 +122,21 @@ public:
/// Remove a constraint
void removeConstraint(const std::string& parName);
/* CompositeFunction own methods */
/// Add a function at the back of the internal function list
virtual int addFunction(IFunction* f);
virtual int addFunction(IFitFunction* f);
/// Returns the pointer to i-th function
IFunction* getFunction(int i)const;
IFitFunction* getFunction(int i)const;
/// Number of functions
int nFunctions()const{return static_cast<int>(m_functions.size());}
/// Remove a function
void removeFunction(int i, bool del=true);
/// Replace a function
void replaceFunction(int i,IFunction* f);
void replaceFunction(int i,IFitFunction* f);
/// Replace a function
void replaceFunction(const IFunction* f_old,IFunction* f_new);
void replaceFunction(const IFitFunction* f_old,IFitFunction* f_new);
/// Get the function index
int functionIndex(int i)const;
/// Get the function index
......@@ -154,7 +148,18 @@ public:
/// Check the function.
void checkFunction();
void setUpNewStuff(boost::shared_array<double> xs = boost::shared_array<double>(),boost::shared_array<double> weights = boost::shared_array<double>());
/* MatrixWorkspace specific */
/// Set the workspace
//void setMatrixWorkspace(boost::shared_ptr<const API::MatrixWorkspace> workspace,int spec,int xMin,int xMax);
///// Function you want to fit to.
//void function(double* out, const double* xValues, const int& nData)const;
///// Derivatives of function with respect to active parameters
//void functionDeriv(Jacobian* out, const double* xValues, const int& nData);
///// Derivatives to be used in covariance matrix calculation.
//void calJacobianForCovariance(Jacobian* out, const double* xValues, const int& nData);
//void setUpNewStuff(boost::shared_array<double> xs = boost::shared_array<double>(),boost::shared_array<double> weights = boost::shared_array<double>());
protected:
/// Function initialization. Declare function parameters in this method.
......@@ -164,13 +169,16 @@ protected:
/// Add a new tie
virtual void addTie(ParameterTie* tie);
int paramOffset(int i)const{return m_paramOffsets[i];}
int activeOffset(int i)const{return m_activeOffsets[i];}
private:
/// Extract function index and parameter name from a variable name
static void parseName(const std::string& varName,int& index, std::string& name);
/// Pointers to the included funtions
std::vector<IFunction*> m_functions;
std::vector<IFitFunction*> m_functions;
/// Individual function parameter offsets (function index in m_functions)
/// e.g. m_functions[i]->activeParameter(m_activeOffsets[i]+1) gives second active parameter of i-th function
std::vector<int> m_activeOffsets;
......@@ -178,9 +186,9 @@ private:
/// e.g. m_functions[i]->parameter(m_paramOffsets[i]+1) gives second declared parameter of i-th function
std::vector<int> m_paramOffsets;
/// Keeps the function index for each declared parameter (parameter declared index)
std::vector<int> m_iFunction;
std::vector<int> m_IFitFunction;
/// Keeps the function index for each active parameter (parameter active index)
std::vector<int> m_iFunctionActive;
std::vector<int> m_IFitFunctionActive;
/// Number of active parameters
int m_nActive;
/// Total number of parameters
......
#ifndef MANTID_API_COMPOSITEFUNCTIONMW_H_
#define MANTID_API_COMPOSITEFUNCTIONMW_H_
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidAPI/CompositeFunction.h"
#include "MantidAPI/IFunctionMW.h"
#ifdef _WIN32
#pragma warning( disable: 4250 )
#endif
namespace Mantid
{
namespace API
{
/** A composite function.
@author Roman Tolchenov, Tessella Support Services plc
@date 20/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 DLLExport CompositeFunctionMW : public CompositeFunction, public IFunctionMW
{
public:
/// Default constructor
CompositeFunctionMW():CompositeFunction(),IFunctionMW(){}
/// Copy contructor
CompositeFunctionMW(const CompositeFunctionMW&);
///Assignment operator
//CompositeFunctionMW& operator=(const CompositeFunctionMW&);
///Destructor
virtual ~CompositeFunctionMW();
/* Overriden methods */
void setWorkspace(boost::shared_ptr<Workspace> ws,const std::string& slicing);
/// Set the workspace
void setMatrixWorkspace(boost::shared_ptr<const API::MatrixWorkspace> workspace,int spec,int xMin,int xMax);
/// Returns the function's name
std::string name()const{return "CompositeFunctionMW";}
/// Writes itself into a string
std::string asString()const;
/// Function you want to fit to.
void function(double* out, const double* xValues, const int& nData)const;
/// Derivatives of function with respect to active parameters
void functionDeriv(Jacobian* out, const double* xValues, const int& nData);
/// Derivatives to be used in covariance matrix calculation.
void calJacobianForCovariance(Jacobian* out, const double* xValues, const int& nData);
void setUpNewStuff(boost::shared_array<double> xs = boost::shared_array<double>(),boost::shared_array<double> weights = boost::shared_array<double>());
};
} // namespace API
} // namespace Mantid
#endif /*MANTID_API_COMPOSITEFUNCTIONMW_H_*/
#ifndef MANTID_API_FUNCTION_H_
#define MANTID_API_FUNCTION_H_
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidKernel/System.h"
#include "MantidKernel/Unit.h"
#include "MantidAPI/IFunction.h"
#include "boost/shared_ptr.hpp"
#include <string>
#include <vector>
#include <boost/shared_array.hpp>
#ifndef HAS_UNORDERED_MAP_H
#include <map>
#else
#include <tr1/unordered_map>
#endif
namespace Mantid
{
namespace API
{
//----------------------------------------------------------------------
// Forward declaration
//----------------------------------------------------------------------
class Jacobian;
class ParameterTie;
class IConstraint;
/** An interface to a function.
@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 DLLExport Function : public IFunction
{
public:
/// Default constructor
Function(){}
/// Copy contructor
Function(const Function&);
/// Assignment operator
Function& operator=(const Function&);
/// Virtual destructor
virtual ~Function();
/// Set i-th parameter
virtual void setParameter(int, const double& value, bool explicitlySet = true);
/// Get i-th parameter
virtual double getParameter(int i)const;
/// Set parameter by name.
virtual void setParameter(const std::string& name, const double& value, bool explicitlySet = true);
/// Get parameter by name.
virtual double getParameter(const std::string& name)const;
/// Total number of parameters
virtual int nParams()const{return static_cast<int>(m_parameters.size());}
/// Returns the index of parameter name
virtual int parameterIndex(const std::string& name)const;
/// Returns the index of a parameter
//virtual int parameterIndex(const double* p)const;
/// Returns the name of parameter i
virtual std::string parameterName(int i)const;
/// Checks if a parameter has been set explicitly
virtual bool isExplicitlySet(int i)const;
/// Number of active (in terms of fitting) parameters
virtual int nActive()const{return static_cast<int>(m_indexMap.size());}
/// Returns "global" index of active parameter i
virtual int indexOfActive(int i)const;
/// Returns the name of active parameter i
virtual std::string nameOfActive(int i)const;
/// Check if a declared parameter i is active
virtual bool isActive(int i)const;
/// Get active index for a declared parameter i
virtual int activeIndex(int i)const;
/// Removes a declared parameter i from the list of active
virtual void removeActive(int i);
/// Restores a declared parameter i to the active status
virtual void restoreActive(int i);
/// Return parameter index from a parameter reference. Usefull for constraints and ties in composite functions
virtual int getParameterIndex(const ParameterReference& ref)const;
/// Get the containing function
IFitFunction* getContainingFunction(const ParameterReference& ref)const;
/// Get the containing function
IFitFunction* getContainingFunction(const IFitFunction* fun);
/// Apply the ties
virtual void applyTies();
/// Remove all ties
virtual void clearTies();
/// Removes i-th parameter's tie
virtual bool removeTie(int i);
/// Get the tie of i-th parameter
virtual ParameterTie* getTie(int i)const;
/// Add a constraint to function
virtual void addConstraint(IConstraint* ic);
/// Get constraint of i-th parameter
virtual IConstraint* getConstraint(int i)const;
/// Remove a constraint
virtual void removeConstraint(const std::string& parName);
/// Set parameters to satisfy constraints
void setParametersToSatisfyConstraints();
/// Calculate numerical derivatives
void calNumericalDeriv(Jacobian* out, const double* xValues, const int& nData);
using IFunction::removeTie;
protected:
/// Function initialization. Declare function parameters in this method.
virtual void init(){};
/// Declare a new parameter
virtual void declareParameter(const std::string& name,double initValue = 0);
/// Add a new tie
virtual void addTie(ParameterTie* tie);
/// Get the address of the parameter. For use in UserFunction with mu::Parser
virtual double* getParameterAddress(int i);
/// Nonvirtual member which removes all declared parameters
void clearAllParameters();
private:
/// The index map. m_indexMap[i] gives the total index for active parameter i
std::vector<int> m_indexMap;
/// Keeps parameter names
std::vector<std::string> m_parameterNames;
/// Keeps parameter values
std::vector<double> m_parameters;
/// Holds parameter ties as <parameter index,tie pointer>
std::vector<ParameterTie*> m_ties;
/// Holds the constraints added to function
std::vector<IConstraint*> m_constraints;
/// Flags of explicitly set parameters
std::vector<bool> m_explicitlySet;
/// Temporary data storage used in functionDeriv
mutable std::vector<double> m_tmpFunctionOutputMinusStep;
/// Temporary data storage used in functionDeriv
mutable std::vector<double> m_tmpFunctionOutputPlusStep;
};
} // namespace API
} // namespace Mantid
#endif /*MANTID_API_FUNCTION_H_*/
......@@ -26,7 +26,6 @@ namespace API
//----------------------------------------------------------------------
// More forward declarations
//----------------------------------------------------------------------
class IFunction;
class IFitFunction;
class CompositeFunction;
class Expression;
......@@ -68,10 +67,10 @@ namespace API
* @param type The function's type
* @return A pointer to the created function
*/
IFunction* createFunction(const std::string& type) const;
IFitFunction* createFunction(const std::string& type) const;
///Creates an instance of a function
IFunction* createInitialized(const std::string& input) const;
IFitFunction* createInitialized(const std::string& input) const;
///Creates an instance of a function
IFitFunction* createFitFunction(const std::string& input) const;
......@@ -93,7 +92,7 @@ namespace API
using Kernel::DynamicFactory<IFitFunction>::createUnwrapped;
/// Create a simple function
IFunction* createSimple(const Expression& expr)const;
IFitFunction* createSimple(const Expression& expr)const;
/// Create a composite function
CompositeFunction* createComposite(const Expression& expr)const;
///Creates an instance of a function
......
......@@ -13,6 +13,10 @@
#include <string>
#include <vector>
#ifdef _WIN32
#pragma warning( disable: 4250 )
#endif
namespace Mantid
{
namespace API
......
#ifndef MANTID_API_IFUNCTION_H_
#define MANTID_API_IFUNCTION_H_
//----------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------
#include "MantidKernel/System.h"
#include "MantidKernel/Unit.h"
#include "MantidKernel/Exception.h"
#include "MantidAPI/IFitFunction.h"
#include "MantidAPI/FunctionFactory.h"
#include "boost/shared_ptr.hpp"
#include "boost/shared_array.hpp"
#include "boost/variant.hpp"
#include <string>
#include <vector>
namespace Mantid
{
namespace CurveFitting
{
class Fit;
}
namespace API
{
#ifndef IGNORE_IFUNCTION_ARGUMENT
#define IGNORE_IFUNCTION_ARGUMENT(x)
#endif
//----------------------------------------------------------------------
// 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 IFunction can be used with the Fit algorithm.
IFunction 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.
IFunction declares method nameOfActive(int 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.
IFunction 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 IFunction 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 IFunction::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
IFunction::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 DLLExport IFunction: public IFitFunction
{
public:
/// Constructor
IFunction():IFitFunction(),m_dataSize(0),m_data(NULL){}
/* Overidden methods */