/// Derivatives of function with respect to active parameters void MultiDomainFunction::functionDeriv(const FunctionDomain& domain, Jacobian& jacobian) { // works only on CompositeDomain if (!dynamic_cast<const CompositeDomain*>(&domain)) { throw std::invalid_argument("Non-CompositeDomain passed to MultiDomainFunction."); } const CompositeDomain& cd = dynamic_cast<const CompositeDomain&>(domain); // domain must not have less parts than m_maxIndex if (cd.getNParts() < m_maxIndex) { throw std::invalid_argument("CompositeDomain has too few parts (" + boost::lexical_cast<std::string>(cd.getNParts()) + ") for MultiDomainFunction (max index " + boost::lexical_cast<std::string>(m_maxIndex) + ")."); } countValueOffsets(cd); // evaluate member functions derivatives for(size_t iFun = 0; iFun < nFunctions(); ++iFun) { // find the domains member function must be applied to std::vector<size_t> domains; getFunctionDomains(iFun, cd, domains); for(auto i = domains.begin(); i != domains.end(); ++i) { const FunctionDomain& d = cd.getDomain(*i); PartialJacobian J(&jacobian,m_valueOffsets[*i],paramOffset(iFun)); getFunction(iFun)->functionDeriv(d,J); } } }
/** * Derivatives of function with respect to active parameters * @param domain :: Function domain to get the arguments from. * @param jacobian :: A Jacobian to store the derivatives. */ void CompositeFunction::functionDeriv(const FunctionDomain &domain, Jacobian &jacobian) { if (getAttribute("NumDeriv").asBool()) { calNumericalDeriv(domain, jacobian); } else { for (size_t iFun = 0; iFun < nFunctions(); ++iFun) { PartialJacobian J(&jacobian, paramOffset(iFun)); getFunction(iFun)->functionDeriv(domain, J); } } }