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);
}
Beispiel #8
0
/**
 * 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);
}