/** * Create a function from an expression. * @param expr :: The input expression * @param parentAttributes :: An output map filled with the attribute name & values of the parent function * @return A pointer to the created function */ IFunction_sptr FunctionFactoryImpl::createSimple(const Expression& expr, std::map<std::string,std::string>& parentAttributes)const { if (expr.name() == "=" && expr.size() > 1) { return createFunction(expr.terms()[1].name()); } if (expr.name() != "," || expr.size() == 0) { inputError(expr.str()); } const std::vector<Expression>& terms = expr.terms(); std::vector<Expression>::const_iterator term = terms.begin(); if (term->name() != "=") inputError(expr.str()); if (term->terms()[0].name() != "name" && term->terms()[0].name() != "composite") { throw std::invalid_argument("Function name must be defined before its parameters"); } std::string fnName = term->terms()[1].name(); IFunction_sptr fun = createFunction(fnName); for(++term;term!=terms.end();++term) {// loop over function's parameters/attributes if (term->name() != "=") inputError(expr.str()); std::string parName = term->terms()[0].name(); std::string parValue = term->terms()[1].str(); if (fun->hasAttribute(parName)) {// set attribute if (parValue.size() > 1 && parValue[0] == '"') {// remove the double quotes parValue = parValue.substr(1,parValue.size()-2); } IFunction::Attribute att = fun->getAttribute(parName); att.fromString(parValue); fun->setAttribute(parName,att); } else if (parName.size() >= 10 && parName.substr(0,10) == "constraint") {// or it can be a list of constraints addConstraints(fun,(*term)[1]); } else if (parName == "ties") { addTies(fun,(*term)[1]); } else if (!parName.empty() && parName[0] == '$') { parName.erase(0,1); parentAttributes[parName] = parValue; } else {// set initial parameter value fun->setParameter(parName,atof(parValue.c_str())); } }// for term fun->applyTies(); return fun; }
IFunction_sptr IqtFit::createUserFunction(const QString &name, bool tie) { IFunction_sptr result = FunctionFactory::Instance().createFunction("UserFunction"); std::string formula; if (name.startsWith("Exp")) { formula = "Intensity*exp(-(x/Tau))"; } else { formula = "Intensity*exp(-(x/Tau)^Beta)"; } IFunction::Attribute att(formula); result->setAttribute("Formula", att); QList<QtProperty *> props = m_properties[name]->subProperties(); for (int i = 0; i < props.size(); i++) { std::string name = props[i]->propertyName().toStdString(); result->setParameter(name, m_dblManager->value(props[i])); // add tie if parameter is fixed if (tie || !props[i]->subProperties().isEmpty()) { std::string value = props[i]->valueText().toStdString(); result->tie(name, value); } } result->applyTies(); return result; }
/* Propagate the attribute to its member functions. * NOTE: we pass this->getAttribute(name) by reference, thus the same * object is shared by the composite function and its members. */ void DiffSphere::trickleDownAttribute(const std::string &name) { for (size_t iFun = 0; iFun < nFunctions(); iFun++) { IFunction_sptr fun = getFunction(iFun); if (fun->hasAttribute(name)) { fun->setAttribute(name, this->getAttribute(name)); } } }