Commit 1b02431b authored by Roman Tolchenov's avatar Roman Tolchenov
Browse files

Re #4158. Changed FunctionFactory to return shared pointers

parent c7ce1969
......@@ -233,6 +233,7 @@ set ( TEST_FILES
test/FunctionDomainTest.h
test/FunctionFactoryTest.h
test/FunctionTest.h
test/FunctionPropertyTest.h
test/FunctionValuesTest.h
test/IEventListTest.h
test/IFunction1DTest.h
......
......@@ -107,9 +107,9 @@ public:
/// Return parameter index from a parameter reference.
size_t getParameterIndex(const ParameterReference& ref)const;
/// Get the containing function
IFunction* getContainingFunction(const ParameterReference& ref)const;
IFunction_sptr getContainingFunction(const ParameterReference& ref)const;
/// Get the containing function
IFunction* getContainingFunction(const IFunction* fun);
//IFunction_sptr getContainingFunction(IFunction_sptr fun);
/// Apply the ties
void applyTies();
......@@ -134,17 +134,17 @@ public:
/* CompositeFunction own methods */
/// Add a function at the back of the internal function list
virtual size_t addFunction(IFunction* f);
virtual size_t addFunction(IFunction_sptr f);
/// Returns the pointer to i-th function
IFunction* getFunction(std::size_t i)const;
IFunction_sptr getFunction(std::size_t i)const;
/// Number of functions
std::size_t nFunctions()const{return m_functions.size();}
/// Remove a function
void removeFunction(size_t i, bool del=true);
void removeFunction(size_t i);
/// Replace a function
void replaceFunction(size_t i,IFunction* f);
void replaceFunction(size_t i,IFunction_sptr f);
/// Replace a function
void replaceFunctionPtr(const IFunction* f_old,IFunction* f_new);
void replaceFunctionPtr(const IFunction_sptr f_old,IFunction_sptr f_new);
/// Get the function index
std::size_t functionIndex(std::size_t i)const;
/// Get the function index
......@@ -173,7 +173,7 @@ private:
static void parseName(const std::string& varName,size_t& index, std::string& name);
/// Pointers to the included funtions
std::vector<IFunction*> m_functions;
std::vector<IFunction_sptr> 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<size_t> m_activeOffsets;
......@@ -193,6 +193,11 @@ private:
};
///shared pointer to the composite function base class
typedef boost::shared_ptr<CompositeFunction> CompositeFunction_sptr;
///shared pointer to the composite function base class (const version)
typedef boost::shared_ptr<const CompositeFunction> CompositeFunction_const_sptr;
/** A Jacobian for individual functions
*/
class PartialJacobian: public Jacobian
......
......@@ -9,6 +9,8 @@
#include "MantidKernel/DynamicFactory.h"
#include "MantidKernel/SingletonHolder.h"
#include <boost/shared_ptr.hpp>
namespace Mantid
{
......@@ -67,13 +69,13 @@ namespace API
* @param type :: The function's type
* @return A pointer to the created function
*/
IFunction* createFunction(const std::string& type) const;
boost::shared_ptr<IFunction> createFunction(const std::string& type) const;
///Creates an instance of a function
IFunction* createInitialized(const std::string& input) const;
boost::shared_ptr<IFunction> createInitialized(const std::string& input) const;
///Creates an instance of a function
IFunction* createFitFunction(const std::string& input) const;
boost::shared_ptr<IFunction> createFitFunction(const std::string& input) const;
/// Query available functions based on the template type
template<typename FunctionType>
......@@ -96,22 +98,22 @@ namespace API
using Kernel::DynamicFactory<IFunction>::createUnwrapped;
/// Create a simple function
IFunction* createSimple(const Expression& expr)const;
boost::shared_ptr<IFunction> createSimple(const Expression& expr)const;
/// Create a composite function
CompositeFunction* createComposite(const Expression& expr)const;
boost::shared_ptr<CompositeFunction> createComposite(const Expression& expr)const;
///Creates an instance of a function
IFunction* createFitFunction(const Expression& expr) const;
boost::shared_ptr<IFunction> createFitFunction(const Expression& expr) const;
/// Throw an exception
void inputError(const std::string& str="")const;
/// Add constraints to the created function
void addConstraints(IFunction* fun,const Expression& expr)const;
void addConstraints(boost::shared_ptr<IFunction> fun,const Expression& expr)const;
/// Add a single constraint to the created function
void addConstraint(IFunction* fun,const Expression& expr)const;
void addConstraint(boost::shared_ptr<IFunction> fun,const Expression& expr)const;
/// Add ties to the created function
void addTies(IFunction* fun,const Expression& expr)const;
void addTies(boost::shared_ptr<IFunction> fun,const Expression& expr)const;
/// Add a tie to the created function
void addTie(IFunction* fun,const Expression& expr)const;
void addTie(boost::shared_ptr<IFunction> fun,const Expression& expr)const;
///static reference to the logger class
Kernel::Logger& g_log;
......
......@@ -5,7 +5,7 @@
// Includes
//----------------------------------------------------------------------
#include "MantidAPI/DllConfig.h"
#include "MantidAPI/IFitFunction.h"
#include "MantidAPI/IFunction.h"
#include "MantidKernel/PropertyWithValue.h"
#include "MantidKernel/Logger.h"
#include "MantidKernel/Exception.h"
......@@ -45,7 +45,7 @@ namespace Mantid
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 FunctionProperty : public Kernel::PropertyWithValue< boost::shared_ptr<IFitFunction> >
class MANTID_API_DLL FunctionProperty : public Kernel::PropertyWithValue< boost::shared_ptr<IFunction> >
{
public:
/// Constructor.
......@@ -58,7 +58,7 @@ namespace Mantid
FunctionProperty& operator=( const FunctionProperty& right );
/// Bring in the PropertyWithValue assignment operator explicitly (avoids VSC++ warning)
virtual boost::shared_ptr<IFitFunction>& operator=( const boost::shared_ptr<IFitFunction>& value );
virtual boost::shared_ptr<IFunction>& operator=( const boost::shared_ptr<IFunction>& value );
///Add the value of another property
virtual FunctionProperty& operator+=( Kernel::Property const * );
......@@ -78,6 +78,16 @@ namespace Mantid
/// Set the value of the property
virtual std::string setValue( const std::string& value );
/**
* Set a property value via a DataItem
* @param data :: A shared pointer to a data item
* @return "" if the assignment was successful or a user level description of the problem
*/
virtual std::string setValue(const boost::shared_ptr<Kernel::DataItem> data)
{
return Kernel::PropertyWithValue< boost::shared_ptr<IFunction> >::setValue(data);
}
/// Checks whether the entered function is valid.
std::string isValid() const;
......
......@@ -296,17 +296,9 @@ public:
/// Return parameter index from a parameter reference. Usefull for constraints and ties in composite functions
virtual size_t getParameterIndex(const ParameterReference& ref)const = 0;
/// Get a function containing the parameter refered to by the reference. In case of a simple function
/// it will be the same as ParameterReference::getFunction(). In case of a CompositeFunction it returns
/// a top-level function that contains the parameter. The return function itself can be a CompositeFunction
/// @param ref :: The Parameter reference
/// @return A pointer to the containing function
virtual IFunction* getContainingFunction(const ParameterReference& ref)const = 0;
/// The same as the method above but the argument is a function
virtual IFunction* getContainingFunction(const IFunction* fun) = 0;
/// Tie a parameter to other parameters (or a constant)
virtual ParameterTie* tie(const std::string& parName,const std::string& expr);
virtual ParameterTie* tie(const std::string& parName, const std::string& expr);
/// Apply the ties
virtual void applyTies() = 0;
/// Removes the tie off a parameter
......@@ -369,7 +361,7 @@ protected:
void calNumericalDeriv(const FunctionDomain& domain, Jacobian& out){}
/// Create an instance of a tie without actually tying it to anything
virtual ParameterTie* createTie(const std::string& parName);
//virtual ParameterTie* createTie(const std::string& parName);
/// Add a new tie
virtual void addTie(ParameterTie* tie) = 0;
......@@ -405,6 +397,11 @@ protected:
IFunction* m_fun;///< pointer to the handled function
};
///shared pointer to the function base class
typedef boost::shared_ptr<IFunction> IFunction_sptr;
///shared pointer to the function base class (const version)
typedef boost::shared_ptr<const IFunction> IFunction_const_sptr;
} // namespace API
} // namespace Mantid
......
......@@ -110,9 +110,9 @@ public:
/// Return parameter index from a parameter reference. Usefull for constraints and ties in composite functions
virtual size_t getParameterIndex(const ParameterReference& ref)const;
/// Get the containing function
IFunction* getContainingFunction(const ParameterReference& ref)const;
IFunction_sptr getContainingFunction(const ParameterReference& ref)const;
/// Get the containing function
IFunction* getContainingFunction(const IFunction* fun);
IFunction_sptr getContainingFunction(IFunction_sptr fun);
/// Apply the ties
virtual void applyTies();
......
......@@ -48,12 +48,11 @@ class MANTID_API_DLL ParameterReference
public:
ParameterReference();
ParameterReference(IFunction* fun, std::size_t index);
IFunction* getFunction() const;
std::size_t getIndex() const;
void reset(IFunction* fun, std::size_t index);
void setParameter(const double& value);
double getParameter() const;
IFunction* getFunction() const;
private:
IFunction* m_function; ///< pointer to the function
std::size_t m_index; ///< parameter index
......
......@@ -49,7 +49,7 @@ namespace API
{
public:
/// Constructor
ParameterTie(IFunction* funct,const std::string& parName);
ParameterTie(IFunction* funct,const std::string& parName,const std::string& expr);
/// Destructor
virtual ~ParameterTie();
/// Set the tie expression
......@@ -57,7 +57,7 @@ public:
/// Evaluate the expression
virtual double eval();
/// Return the string that can be used to recreate this tie
virtual std::string asString(const IFunction* fun = 0)const;
virtual std::string asString(const IFunction* fun = NULL)const;
/// Check if the tie has any references to certain parameters
bool findParametersOf(const IFunction* fun)const;
......
......@@ -46,8 +46,6 @@ CompositeFunction& CompositeFunction::operator=(const CompositeFunction& f)
///Destructor
CompositeFunction::~CompositeFunction()
{
for(size_t i=0;i<nFunctions();i++)
if (m_functions[i]) delete m_functions[i];
}
......@@ -72,14 +70,14 @@ void CompositeFunction::init()
std::string CompositeFunction::asString()const
{
std::ostringstream ostr;
if (name() != "CompositeFunctionMW")
if (name() != "CompositeFunction")
{
ostr << "composite=" <<name() << ";";
}
for(size_t i=0;i<nFunctions();i++)
{
IFunction* fun = getFunction(i);
bool isComp = dynamic_cast<CompositeFunction*>(fun) != 0;
IFunction_sptr fun = getFunction(i);
bool isComp = boost::dynamic_pointer_cast<CompositeFunction>(fun) != 0;
if (isComp) ostr << '(';
ostr << fun->asString();
if (isComp) ostr << ')';
......@@ -94,8 +92,8 @@ std::string CompositeFunction::asString()const
const ParameterTie* tie = getTie(i);
if (tie)
{
IFunction* fun = getFunction(functionIndex(i));
std::string tmp = tie->asString(fun);
IFunction_sptr fun = getFunction(functionIndex(i));
std::string tmp = tie->asString(fun.get());
if (tmp.empty())
{
tmp = tie->asString(this);
......@@ -355,13 +353,13 @@ void CompositeFunction::checkFunction()
m_IFunction.clear();
m_IFunctionActive.clear();
std::vector<IFunction*> functions(m_functions.begin(),m_functions.end());
std::vector<IFunction_sptr> functions(m_functions.begin(),m_functions.end());
m_functions.clear();
for(std::vector<IFunction*>::size_type i=0;i<functions.size();i++)
for(std::vector<IFunction_sptr>::size_type i=0;i<functions.size();i++)
{
IFunction* f = functions[i];
CompositeFunction* cf = dynamic_cast<CompositeFunction*>(f);
IFunction_sptr f = functions[i];
CompositeFunction_sptr cf = boost::dynamic_pointer_cast<CompositeFunction>(f);
if (cf) cf->checkFunction();
addFunction(f);
}
......@@ -371,7 +369,7 @@ void CompositeFunction::checkFunction()
* @param f :: A pointer to the added function
* @return The function index
*/
size_t CompositeFunction::addFunction(IFunction* f)
size_t CompositeFunction::addFunction(IFunction_sptr f)
{
m_IFunction.insert(m_IFunction.end(),f->nParams(), m_functions.size());
m_IFunctionActive.insert(m_IFunctionActive.end(),f->nActive(),m_functions.size());
......@@ -398,12 +396,12 @@ size_t CompositeFunction::addFunction(IFunction* f)
* @param i :: The index of the function to remove
* @param del :: The deletion flag. If true the function will be deleted otherwise - simply detached
*/
void CompositeFunction::removeFunction(size_t i, bool del)
void CompositeFunction::removeFunction(size_t i)
{
if ( i >= nFunctions() )
throw std::out_of_range("Function index out of range.");
IFunction* fun = getFunction(i);
IFunction_sptr fun = getFunction(i);
size_t dna = fun->nActive();
size_t dnp = fun->nParams();
......@@ -411,7 +409,7 @@ void CompositeFunction::removeFunction(size_t i, bool del)
for(size_t j=0;j<nParams();)
{
ParameterTie* tie = getTie(j);
if (tie && tie->findParametersOf(fun))
if (tie && tie->findParametersOf(fun.get()))
{
removeTie(j);
}
......@@ -473,10 +471,6 @@ void CompositeFunction::removeFunction(size_t i, bool del)
m_paramOffsets.erase(m_paramOffsets.begin()+i);
m_functions.erase(m_functions.begin()+i);
if (del)
{
delete fun;
}
}
/** Replace a function with a new one. The old function is deleted.
......@@ -485,12 +479,12 @@ void CompositeFunction::removeFunction(size_t i, bool del)
* a member of this composite function nothing happens
* @param f_new :: A pointer to the new function
*/
void CompositeFunction::replaceFunctionPtr(const IFunction* f_old,IFunction* f_new)
void CompositeFunction::replaceFunctionPtr(const IFunction_sptr f_old,IFunction_sptr f_new)
{
std::vector<IFunction*>::const_iterator it =
std::vector<IFunction_sptr>::const_iterator it =
std::find(m_functions.begin(),m_functions.end(),f_old);
if (it == m_functions.end()) return;
std::vector<IFunction*>::difference_type iFun = it - m_functions.begin();
std::vector<IFunction_sptr>::difference_type iFun = it - m_functions.begin();
replaceFunction(iFun,f_new);
}
......@@ -498,12 +492,12 @@ void CompositeFunction::replaceFunctionPtr(const IFunction* f_old,IFunction* f_n
* @param i :: The index of the function to replace
* @param f :: A pointer to the new function
*/
void CompositeFunction::replaceFunction(size_t i,IFunction* f)
void CompositeFunction::replaceFunction(size_t i,IFunction_sptr f)
{
if ( i >= nFunctions() )
throw std::out_of_range("Function index out of range.");
IFunction* fun = getFunction(i);
IFunction_sptr fun = getFunction(i);
size_t na_old = fun->nActive();
size_t np_old = fun->nParams();
......@@ -569,14 +563,13 @@ void CompositeFunction::replaceFunction(size_t i,IFunction* f)
}
m_functions[i] = f;
delete fun;
}
/**
* @param i :: The index of the function
* @return function at the requested index
*/
IFunction* CompositeFunction::getFunction(std::size_t i)const
IFunction_sptr CompositeFunction::getFunction(std::size_t i)const
{
if ( i >= nFunctions() )
{
......@@ -790,7 +783,7 @@ size_t CompositeFunction::getParameterIndex(const ParameterReference& ref)const
}
for(size_t iFun=0;iFun<nFunctions();iFun++)
{
IFunction* fun = getFunction(iFun);
IFunction_sptr fun = getFunction(iFun);
size_t iLocalIndex = fun->getParameterIndex(ref);
if (iLocalIndex < fun->nParams())
{
......@@ -801,46 +794,43 @@ size_t CompositeFunction::getParameterIndex(const ParameterReference& ref)const
}
/**
* Returns the shrared pointer to the function conataining a parameter
* @param ref :: The reference
* @return A function containing parameter pointed to by ref
*/
IFunction* CompositeFunction::getContainingFunction(const ParameterReference& ref)const
IFunction_sptr CompositeFunction::getContainingFunction(const ParameterReference& ref)const
{
if (ref.getFunction() == this && ref.getIndex() < nParams())
{
return ref.getFunction();
}
for(size_t iFun=0;iFun<nFunctions();iFun++)
{
IFunction* fun = getFunction(iFun)->getContainingFunction(ref);
if (fun)
IFunction_sptr fun = getFunction(iFun);
if (fun->getParameterIndex(ref) < fun->nParams())
{
return getFunction(iFun);
return fun;
}
}
return NULL;
}
/**
* @param fun :: The searched function
* @return A function containing the argument function fun
*/
IFunction* CompositeFunction::getContainingFunction(const IFunction* fun)
{
if (fun == this)
{
return this;
}
for(size_t iFun=0;iFun<nFunctions();iFun++)
{
IFunction* f = getFunction(iFun)->getContainingFunction(fun);
if (f)
{
return getFunction(iFun);
}
}
return NULL;
}
return IFunction_sptr();
}
///**
// * @param fun :: The searched function
// * @return A function containing the argument function fun
// */
//IFunction_sptr CompositeFunction::getContainingFunction(IFunction_sptr fun)
//{
// if (fun.get() == this)
// {
// return fun;
// }
// for(size_t iFun=0;iFun<nFunctions();iFun++)
// {
// IFunction_sptr f = getFunction(iFun);
// if (f == fun)
// {
// return getFunction(iFun);
// }
// }
// return IFunction_sptr();
//}
} // namespace API
} // namespace Mantid
......@@ -29,13 +29,9 @@ namespace Mantid
{
}
IFunction* FunctionFactoryImpl::createFunction(const std::string& type) const
IFunction_sptr FunctionFactoryImpl::createFunction(const std::string& type) const
{
IFunction* fun = dynamic_cast<IFunction*>(createUnwrapped(type));
if (!fun)
{
throw std::runtime_error("Function "+type+" cannot be cast to IFunction");
}
IFunction_sptr fun = create(type);
fun->initialize();
return fun;
}
......@@ -50,7 +46,7 @@ namespace Mantid
* input = "name=LinearBackground,A0=0,A1=1; name = Gaussian, PeakCentre=10.,Sigma=1"
* @return A pointer to the created function
*/
IFunction* FunctionFactoryImpl::createInitialized(const std::string& input) const
IFunction_sptr FunctionFactoryImpl::createInitialized(const std::string& input) const
{
Expression expr;
try
......@@ -66,7 +62,7 @@ namespace Mantid
if (e.name() == ";")
{
IFunction* fun = createComposite(e);
IFunction_sptr fun = createComposite(e);
if (!fun) inputError();
return fun;
}
......@@ -80,7 +76,7 @@ namespace Mantid
* @param expr :: The input expression
* @return A pointer to the created function
*/
IFunction* FunctionFactoryImpl::createSimple(const Expression& expr)const
IFunction_sptr FunctionFactoryImpl::createSimple(const Expression& expr)const
{
if (expr.name() == "=" && expr.size() > 1)
{
......@@ -102,7 +98,7 @@ namespace Mantid
}
std::string fnName = term->terms()[1].name();
IFunction* fun = createFunction(fnName);
IFunction_sptr fun = createFunction(fnName);
for(++term;term!=terms.end();++term)
{// loop over function's parameters/attributes
if (term->name() != "=") inputError(expr.str());
......@@ -140,31 +136,31 @@ namespace Mantid
* @param expr :: The input expression
* @return A pointer to the created function
*/
CompositeFunction* FunctionFactoryImpl::createComposite(const Expression& expr)const
CompositeFunction_sptr FunctionFactoryImpl::createComposite(const Expression& expr)const
{
if (expr.name() != ";") inputError(expr.str());
if (expr.size() == 0)
{
return 0;
return CompositeFunction_sptr();
}
const std::vector<Expression>& terms = expr.terms();
std::vector<Expression>::const_iterator it = terms.begin();
const Expression& term = it->bracketsRemoved();
CompositeFunction* cfun = 0;
CompositeFunction_sptr cfun;
if (term.name() == "=")
{
if (term.terms()[0].name() == "composite")
{
cfun = dynamic_cast<CompositeFunction*>(createFunction(term.terms()[1].name()));
cfun = boost::dynamic_pointer_cast<CompositeFunction>(createFunction(term.terms()[1].name()));
if (!cfun) inputError(expr.str());
++it;
}
else if (term.terms()[0].name() == "name")
{
cfun = dynamic_cast<CompositeFunction*>(createFunction("CompositeFunction"));
cfun = boost::dynamic_pointer_cast<CompositeFunction>(createFunction("CompositeFunction"));
if (!cfun) inputError(expr.str());
}
else
......@@ -179,13 +175,13 @@ namespace Mantid
{
if (firstTerm->terms()[0].name() == "composite")
{
cfun = dynamic_cast<CompositeFunction*>(createSimple(term));
cfun = boost::dynamic_pointer_cast<CompositeFunction>(createSimple(term));
if (!cfun) inputError(expr.str());
++it;
}
else if (firstTerm->terms()[0].name() == "name")
{
cfun = dynamic_cast<CompositeFunction*>(createFunction("CompositeFunction"));
cfun = boost::dynamic_pointer_cast<CompositeFunction>(createFunction("CompositeFunction"));
if (!cfun) inputError(expr.str());
}
else
......@@ -196,7 +192,7 @@ namespace Mantid
}
else if (term.name() == ";")
{
cfun = dynamic_cast<CompositeFunction*>(createFunction("CompositeFunction"));
cfun = boost::dynamic_pointer_cast<CompositeFunction>(createFunction("CompositeFunction"));
if (!cfun) inputError(expr.str());
}
else
......@@ -207,7 +203,7 @@ namespace Mantid
for(;it!=terms.end();++it)
{
const Expression& term = it->bracketsRemoved();
IFunction* fun = NULL;