TEST(FunctionFactoryTest, CreateCompositeFunctionTest) { std::string ini = "CompositeFunction(" "FunctionFactoryTestFunction(A=10,B=20)," "FunctionFactoryTestFunction(A=30,B=40)" ")"; IFunction_sptr fun = FunctionFactory::instance().createFitFunction(ini); EXPECT_TRUE( fun.get() != nullptr ); CompositeFunction_sptr cf = boost::dynamic_pointer_cast<CompositeFunction>(fun); EXPECT_TRUE( cf.get() != nullptr ); EXPECT_EQ( cf->nFunctions(), 2 ); auto f1 = cf->getFunction(0); auto f2 = cf->getFunction(1); EXPECT_EQ(f1->getParameter("A"),10); EXPECT_EQ(f1->getParameter("B"),20); EXPECT_EQ(f2->getParameter("A"),30); EXPECT_EQ(f2->getParameter("B"),40); EXPECT_EQ(cf->getParameter("f0.A"),10); EXPECT_EQ(cf->getParameter("f0.B"),20); EXPECT_EQ(cf->getParameter("f1.A"),30); EXPECT_EQ(cf->getParameter("f1.B"),40); std::cerr << '\n' << fun->asString(true) << '\n' << std::endl; IFunction_sptr fun1 = FunctionFactory::instance().createFitFunction(ini); EXPECT_TRUE( fun1.get() != nullptr ); cf = boost::dynamic_pointer_cast<CompositeFunction>(fun1); EXPECT_TRUE( cf.get() != nullptr ); EXPECT_EQ( cf->nFunctions(), 2 ); EXPECT_EQ(cf->getParameter("f0.A"),10); EXPECT_EQ(cf->getParameter("f0.B"),20); EXPECT_EQ(cf->getParameter("f1.A"),30); EXPECT_EQ(cf->getParameter("f1.B"),40); }
TEST(FunctionFactoryTest, CreateFitFunctionTest) { IFunction_sptr fun = FunctionFactory::instance().createFitFunction("FunctionFactoryTestFunction(A=10,B=20)"); EXPECT_TRUE( fun.get() != nullptr ); EXPECT_EQ(fun->getParameter("A"),10); EXPECT_EQ(fun->getParameter("B"),20); //std::cerr << fun->asString() << std::endl; }
/// Execute void EstimatePeakErrors::exec() { IFunction_sptr function = getProperty("Function"); ITableWorkspace_sptr results = WorkspaceFactory::Instance().createTable("TableWorkspace"); results->addColumn("str", "Parameter"); results->addColumn("double", "Value"); results->addColumn("double", "Error"); auto matrix = function->getCovarianceMatrix(); if (!matrix) { g_log.warning() << "Function doesn't have covariance matrix.\n"; setProperty("OutputWorkspace", results); return; } IPeakFunction *peak = dynamic_cast<IPeakFunction *>(function.get()); if (peak) { GSLMatrix covariance(*matrix); calculatePeakValues(*peak, *results, covariance, ""); } else { CompositeFunction *cf = dynamic_cast<CompositeFunction *>(function.get()); if (cf) { size_t ip = 0; for (size_t i = 0; i < cf->nFunctions(); ++i) { IFunction *fun = cf->getFunction(i).get(); size_t np = fun->nParams(); peak = dynamic_cast<IPeakFunction *>(fun); if (peak) { std::string prefix = "f" + std::to_string(i) + "."; GSLMatrix covariance(*matrix, ip, ip, np, np); calculatePeakValues(*peak, *results, covariance, prefix); } ip += np; } } else { g_log.warning() << "Function has no peaks.\n"; } } setProperty("OutputWorkspace", results); }
/** Set parameter fitting setup (boundary, fix or unfix) to function from Parameter map */ void RefinePowderInstrumentParameters2::setFunctionParameterFitSetups(IFunction_sptr function, map<string, Parameter> params) { // 1. Prepare vector<string> funparamnames = m_positionFunc->getParameterNames(); // 2. Set up std::map<std::string, Parameter>::iterator paramiter; for (size_t i = 0; i < funparamnames.size(); ++i) { string parname = funparamnames[i]; paramiter = params.find(parname); if (paramiter != params.end()) { // Found, set up the parameter Parameter& param = paramiter->second; if (param.fit) { // If fit. Unfix it and set up constraint function->unfix(i); double lowerbound = param.minvalue; double upperbound = param.maxvalue; if (lowerbound >= -DBL_MAX*0.1 || upperbound <= DBL_MAX*0.1) { // If there is a boundary BoundaryConstraint *bc = new BoundaryConstraint(function.get(), parname, lowerbound, upperbound, false); function->addConstraint(bc); } } else { // If fix. function->fix(i); } } else { // Not found and thus quit stringstream errss; errss << "Peak profile parameter " << parname << " is not found in input parameters. "; g_log.error(errss.str()); throw runtime_error(errss.str()); } } // ENDFOR parameter name g_log.notice() << "Fit function:\n" << function->asString() << "\n"; return; }
TEST(FunctionFactoryTest, CreateFitFunction_with_brackets_Test) { IFunction_sptr fun = FunctionFactory::instance().createFitFunction("FunctionFactoryTestFunction()"); EXPECT_TRUE( fun.get() != nullptr ); //Function1DTestFunction fun; FunctionDomain1DVector domain(0.0,1.0,10); FunctionValues values(domain); fun->function(domain,values); for(size_t i = 0; i < domain.size(); ++i) { double x = domain[i]; EXPECT_EQ( 1.0 * x - 3.0, values.getCalculated(i)); } }
/** * Add a new workspace to the fit. The workspace is in the property named * workspacePropertyName. * @param workspacePropertyName :: A workspace property name (eg InputWorkspace * or InputWorkspace_2). The property must already exist in the algorithm. * @param addProperties :: allow for declaration of properties that specify the * dataset within the workspace to fit to. */ void IFittingAlgorithm::addWorkspace(const std::string &workspacePropertyName, bool addProperties) { // get the workspace API::Workspace_const_sptr ws = getProperty(workspacePropertyName); // m_function->setWorkspace(ws); const size_t n = std::string("InputWorkspace").size(); const std::string suffix = (workspacePropertyName.size() > n) ? workspacePropertyName.substr(n) : ""; const size_t index = suffix.empty() ? 0 : boost::lexical_cast<size_t>(suffix.substr(1)); IFunction_sptr fun = getProperty("Function"); setDomainType(); IDomainCreator *creator = createDomainCreator( fun.get(), ws.get(), workspacePropertyName, this, m_domainType); if (!m_domainCreator) { if (m_workspacePropertyNames.empty()) { // this defines the function and fills in m_workspacePropertyNames with // names of the sort InputWorkspace_# setFunction(); } auto multiFun = boost::dynamic_pointer_cast<API::MultiDomainFunction>(fun); if (multiFun) { auto multiCreator = new MultiDomainCreator(this, m_workspacePropertyNames); multiCreator->setCreator(index, creator); m_domainCreator.reset(multiCreator); creator->declareDatasetProperties(suffix, addProperties); } else { m_domainCreator.reset(creator); creator->declareDatasetProperties(suffix, addProperties); } } else { boost::shared_ptr<MultiDomainCreator> multiCreator = boost::dynamic_pointer_cast<MultiDomainCreator>(m_domainCreator); if (!multiCreator) { auto &reference = *m_domainCreator.get(); throw std::runtime_error( std::string("MultiDomainCreator expected, found ") + typeid(reference).name()); } if (!multiCreator->hasCreator(index)) { creator->declareDatasetProperties(suffix, addProperties); } multiCreator->setCreator(index, creator); } }
/** Remove a function * @param i :: The index of the function to remove */ void CompositeFunction::removeFunction(size_t i) { if (i >= nFunctions()) { throw std::out_of_range("Function index (" + std::to_string(i) + ") out of range (" + std::to_string(nFunctions()) + ")."); } IFunction_sptr fun = getFunction(i); // Reduction in parameters size_t dnp = fun->nParams(); for (size_t j = 0; j < nParams();) { ParameterTie *tie = getTie(j); if (tie && tie->findParametersOf(fun.get())) { removeTie(j); } else { j++; } } // Shift down the function indeces for parameters for (auto it = m_IFunction.begin(); it != m_IFunction.end();) { if (*it == i) { it = m_IFunction.erase(it); } else { if (*it > i) { *it -= 1; } ++it; } } m_nParams -= dnp; // Shift the parameter offsets down by the total number of i-th function's // params for (size_t j = i + 1; j < nFunctions(); j++) { m_paramOffsets[j] -= dnp; } m_paramOffsets.erase(m_paramOffsets.begin() + i); m_functions.erase(m_functions.begin() + i); }
/** * Add a constraints to the function * @param fun :: The function * @param expr :: The constraint expression. */ void FunctionFactoryImpl::addConstraint(IFunction_sptr fun, const Expression &expr) const { IConstraint *c = ConstraintFactory::Instance().createInitialized(fun.get(), expr); fun->addConstraint(c); }