/** * 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; }
/** * Create a fitting function from an expression. * @param expr :: The input expression made by parsing the input string to createFitFunction(const std::string& input) */ IFitFunction* FunctionFactoryImpl::createFitFunction(const Expression& expr) const { const Expression& e = expr.bracketsRemoved(); std::string fnName = e.name(); IFitFunction* fun = createUnwrapped(fnName); if (!fun) { throw std::runtime_error("Cannot create function "+fnName); } fun->initialize(); const std::vector<Expression>& terms = e.terms(); std::vector<Expression>::const_iterator term = terms.begin(); for(;term!=terms.end();++term) {// loop over function's parameters/attributes if (term->name() == "=") { 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); } IFitFunction::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 {// set initial parameter value fun->setParameter(parName,atof(parValue.c_str())); } } else // if the term isn't a name=value pair it could be a member function of a composite function { throw Kernel::Exception::NotImplementedError("Composite functions are not implemented yet for IFitFunction"); //CompositeFunction* cfun = dynamic_cast<CompositeFunction*>(fun); //if (!cfun) //{ // throw std::runtime_error("Cannot add a function to a non-composite function "+fnName); //} //IFitFunction* mem = createFitFunction(*term); //cfun->addFunction(mem); } }// for term return fun; }
Foam::sixDoFRigidBodyMotion::sixDoFRigidBodyMotion ( const dictionary& dict, const dictionary& stateDict ) : motionState_(stateDict), motionState0_(), restraints_(), constraints_(), tConstraints_(tensor::I), rConstraints_(tensor::I), initialCentreOfMass_ ( dict.lookupOrDefault ( "initialCentreOfMass", vector(dict.lookup("centreOfMass")) ) ), initialCentreOfRotation_(initialCentreOfMass_), initialQ_ ( dict.lookupOrDefault ( "initialOrientation", dict.lookupOrDefault("orientation", tensor::I) ) ), mass_(readScalar(dict.lookup("mass"))), momentOfInertia_(dict.lookup("momentOfInertia")), aRelax_(dict.lookupOrDefault<scalar>("accelerationRelaxation", 1.0)), aDamp_(dict.lookupOrDefault<scalar>("accelerationDamping", 1.0)), report_(dict.lookupOrDefault<Switch>("report", false)), solver_(sixDoFSolver::New(dict.subDict("solver"), *this)) { addRestraints(dict); // Set constraints and initial centre of rotation // if different to the centre of mass addConstraints(dict); // If the centres of mass and rotation are different ... vector R(initialCentreOfMass_ - initialCentreOfRotation_); if (magSqr(R) > VSMALL) { // ... correct the moment of inertia tensor using parallel axes theorem momentOfInertia_ += mass_*diag(I*magSqr(R) - sqr(R)); // ... and if the centre of rotation is not specified for motion state // update it if (!stateDict.found("centreOfRotation")) { motionState_.centreOfRotation() = initialCentreOfRotation_; } } // Save the old-time motion state motionState0_ = motionState_; }
Foam::sixDoFRigidBodyMotion::sixDoFRigidBodyMotion(const dictionary& dict) : motionState_(dict), restraints_(), restraintNames_(), constraints_(), constraintNames_(), maxConstraintIterations_(0), initialCentreOfMass_ ( dict.lookupOrDefault("initialCentreOfMass", centreOfMass()) ), initialQ_ ( dict.lookupOrDefault("initialOrientation", Q()) ), momentOfInertia_(dict.lookup("momentOfInertia")), mass_(readScalar(dict.lookup("mass"))), cDamp_(dict.lookupOrDefault<scalar>("accelerationDampingCoeff", 0.0)), aLim_(dict.lookupOrDefault<scalar>("accelerationLimit", VGREAT)), report_(dict.lookupOrDefault<Switch>("report", false)) { addRestraints(dict); addConstraints(dict); }
void HtmlHeaderMetadataItemVisitor::visitTable(Table& /*table*/) { emptyTitles(); addSummary(); addConstraints(); addIndices(); addTriggers(); addPrivileges(); addDependencies(); addDDL(); }
static Matrix optimizeWithDerivative(float& bestCost, const NeuralNetwork* network, const Matrix& initialData, unsigned int neuron) { auto input = network->convertToBlockSparseForLayerInput(network->front(), initialData); auto reference = network->convertToBlockSparseForLayerOutput(network->back(), generateReferenceForNeuron(network, neuron)); auto data = network->createBackPropagation(); data->setInput(&input); data->setReferenceOutput(&reference); auto bestSoFar = input; bestCost = data->computeInputCost(); std::string solverType = util::KnobDatabase::getKnobValue( "NeuronVisualizer::SolverType", "GradientDescentSolver"); auto solver = optimizer::GeneralDifferentiableSolverFactory::create(solverType); assert(solver != nullptr); addConstraints(solver); util::log("NeuronVisualizer") << " Initial inputs are : " << initialData.toString(); util::log("NeuronVisualizer") << " Initial reference is : " << generateReferenceForNeuron(network, neuron).toString(); util::log("NeuronVisualizer") << " Initial output is : " << network->runInputs(initialData).toString(); util::log("NeuronVisualizer") << " Initial cost is : " << bestCost << "\n"; try { CostAndGradientFunction costAndGradient(data, bestCost, 0.000002f); bestCost = solver->solve(bestSoFar, costAndGradient); } catch(...) { util::log("NeuronVisualizer") << " solver produced an error.\n"; delete solver; delete data; throw; } delete solver; delete data; util::log("NeuronVisualizer") << " solver produced new cost: " << bestCost << ".\n"; util::log("NeuronVisualizer") << " final input is : " << bestSoFar.toString(); util::log("NeuronVisualizer") << " final output is : " << network->runInputs(bestSoFar).toString(); return bestSoFar.toMatrix(); }
main(int argc, char* argv[]) { typedef GOFactory < FT > Fact; typedef WTraverse < Fact > Traverse; typedef BNBSeqSolver < Traverse > Solver; int n = N; FT z[n]; F f(n); GOInitialData<FT> id; SegVecDecomp<Fact> decomp; LipzGradDiscarder<FT> dscg; dscg.setName("Objective"); SimpleConstraintChecker<FT> scheck; Fact fact; init(n, &f, id); fact.setInitialData(&id); addConstraints(n, scheck, fact, id); fact.setConstraintChecker(&scheck); dscg.setEps(EPS); dscg.setInitialData(&id); // dscg.getDebugOptions() |= LipzGradDiscarder<FT>::DebugOptions::PRINT_BOUNDS; dscg.setObjective(&f); dscg.getOptions() &= ~LipzGradDiscarder<FT>::Options::CHECK_GRAD; dscg.getOptions() &= ~LipzGradDiscarder<FT>::Options::CHECK_GRAD_COMP; dscg.getOptions() &= ~LipzGradDiscarder<FT>::Options::UPDATE_RECORD; dscg.getOptions() |= LipzGradDiscarder<FT>::Options::DO_PRIMARY_BALL_CUT; fact.addDiscarder(&dscg); fact.addDiscarder(&decomp); //fact.getDebugOptions() |= Fact::DebugOptions::DO_DEBUG; Solver solver(&fact); solver.setDebugOptions( Solver::Options::PRINT_RESULTING_STAT // | Solver::Options::PRINT_STATE ); //solver.Traverse::setDebugOptions(Traverse::Options::PRINT_STEP); // solver.setDebugOptions(Solver::Options::PRINT_RESULTING_STAT | Solver::Options::PRINT_INITIAL_VAL); //solver.setRecord(n - 1); solver.solve(); if(solver.getSolutionContainer()->empty()) printf("Empty container\n"); printf("Minimum = %s\n", solver.getSolutionContainer()->top().toString().c_str()); }
//----------------------------------------------------------------------- void Triangulator::triangulate(const Shape& shape, std::vector<int>& output) { // Do the Delaunay triangulation PointList pl = shape.getPoints(); DelaunayTriangleBuffer dtb; delaunay(pl, dtb); addConstraints(shape, dtb); //Outputs index buffer for (DelaunayTriangleBuffer::iterator it = dtb.begin(); it!=dtb.end();it++) { output.push_back(it->i[0]); output.push_back(it->i[1]); output.push_back(it->i[2]); } }
/** * Create and connect actions */ void FunctionBrowser::createActions() { m_actionAddFunction = new QAction("Add function",this); connect(m_actionAddFunction,SIGNAL(triggered()),this,SLOT(addFunction())); m_actionRemoveFunction = new QAction("Remove function",this); connect(m_actionRemoveFunction,SIGNAL(triggered()),this,SLOT(removeFunction())); m_actionFixParameter = new QAction("Fix",this); connect(m_actionFixParameter,SIGNAL(triggered()),this,SLOT(fixParameter())); m_actionRemoveTie = new QAction("Remove tie",this); connect(m_actionRemoveTie,SIGNAL(triggered()),this,SLOT(removeTie())); m_actionAddTie = new QAction("Add tie",this); connect(m_actionAddTie,SIGNAL(triggered()),this,SLOT(addTie())); m_actionFromClipboard = new QAction("Copy from clipboard",this); connect(m_actionFromClipboard,SIGNAL(triggered()),this,SLOT(copyFromClipboard())); m_actionToClipboard = new QAction("Copy to clipboard",this); connect(m_actionToClipboard,SIGNAL(triggered()),this,SLOT(copyToClipboard())); m_actionConstraints = new QAction("Custom",this); connect(m_actionConstraints,SIGNAL(triggered()),this,SLOT(addConstraints())); m_actionConstraints10 = new QAction("10%",this); connect(m_actionConstraints10,SIGNAL(triggered()),this,SLOT(addConstraints10())); m_actionConstraints50 = new QAction("50%",this); connect(m_actionConstraints50,SIGNAL(triggered()),this,SLOT(addConstraints50())); m_actionRemoveConstraints = new QAction("Remove constraints",this); connect(m_actionRemoveConstraints,SIGNAL(triggered()),this,SLOT(removeConstraints())); m_actionRemoveConstraint = new QAction("Remove",this); connect(m_actionRemoveConstraint,SIGNAL(triggered()),this,SLOT(removeConstraint())); }
/** * Create a function from an expression. * @param expr :: The input expression * @return A pointer to the created function */ IFitFunction* FunctionFactoryImpl::createSimple(const Expression& expr)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(); IFitFunction* fun = createFunction(fnName); std::string wsName,wsParam; 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); } IFitFunction::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 == "Workspace") { wsName = parValue; } else if (parName == "WSParam") { wsParam = parValue; } else {// set initial parameter value fun->setParameter(parName,atof(parValue.c_str())); } }// for term if (!wsName.empty()) { Workspace_sptr ws = AnalysisDataService::Instance().retrieve(wsName); fun->setWorkspace(ws,wsParam); } return fun; }
/** * Create a composite function from an expression. * @param expr :: The input expression * @return A pointer to the created function */ CompositeFunction* FunctionFactoryImpl::createComposite(const Expression& expr)const { if (expr.name() != ";") inputError(expr.str()); if (expr.size() == 0) { return 0; } const std::vector<Expression>& terms = expr.terms(); std::vector<Expression>::const_iterator it = terms.begin(); const Expression& term = it->bracketsRemoved(); CompositeFunction* cfun = 0; std::string wsName,wsParam; if (term.name() == "=") { if (term.terms()[0].name() == "composite") { cfun = dynamic_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("CompositeFunctionMW")); if (!cfun) inputError(expr.str()); } else { inputError(expr.str()); } } else if (term.name() == ",") { std::vector<Expression>::const_iterator firstTerm = term.terms().begin(); if (firstTerm->name() == "=") { if (firstTerm->terms()[0].name() == "composite") { cfun = dynamic_cast<CompositeFunction*>(createSimple(term)); if (!cfun) inputError(expr.str()); ++it; } else if (firstTerm->terms()[0].name() == "name") { cfun = dynamic_cast<CompositeFunction*>(createFunction("CompositeFunctionMW")); if (!cfun) inputError(expr.str()); } else { inputError(expr.str()); } } } else if (term.name() == ";") { cfun = dynamic_cast<CompositeFunction*>(createFunction("CompositeFunctionMW")); if (!cfun) inputError(expr.str()); } else { inputError(expr.str()); } for(;it!=terms.end();++it) { const Expression& term = it->bracketsRemoved(); IFitFunction* fun = NULL; if (term.name() == ";") { fun = createComposite(term); if (!fun) continue; } else { std::string parName = term[0].name(); std::string parValue = term[1].str(); if (term[0].name().size() >= 10 && term[0].name().substr(0,10) == "constraint") { addConstraints(cfun,term[1]); continue; } else if (term[0].name() == "ties") { addTies(cfun,term[1]); continue; } else if (parName == "Workspace") { wsName = parValue; } else if (parName == "WSParam") { wsParam = parValue; } else { fun = createSimple(term); } } cfun->addFunction(fun); } if (!wsName.empty()) { Workspace_sptr ws = AnalysisDataService::Instance().retrieve(wsName); cfun->setWorkspace(ws,wsParam); } return cfun; }
LPP* MorpionLPP::getLPP() { setComment(gameId()); // each possible move is a structural variable // our goal is to maximize sum over all variables for (const Move& m: b.getMoveList()) { std::string v_name = to_string(m); setVariableBounds(v_name, 0.0, 1.0); getObjective().push_back(std::pair<std::string, double>(v_name, 1.0)); // Constraint for exact problems. // // mv_ variables are either 0 or 1 (i.e. the move is either played or not) if (getFlag("exact") || getFlag("binary_moves")) { setVariableBoolean(v_name, true); } } // each segment gives us constraints: // (1) if the segment is placed in the starting position // (a) sum of weights of moves that place this segment <= 0 // (b) 1 - sum of weights of moves that remove this segment >= 0 // i.e. sum of weights of moves that remove this segment <= 1 // (2) if the segment is not placed in the starting position // (a) sum of weights of moves that place this segment <= 1 // (b) sum of weights of moves that place this segment // - sum of weights of moves that remove this segment >= 0 for (const Segment& s: b.getSegmentList()) { int x = s.first.x; int y = s.first.y; int d = s.second; std::string constr_name = "segment_" + to_string(x) + "_" + to_string(y) + "_" + to_string(d); if (b.hasDot(Dot(x,y))) { // (1a) { Constraint constr; for (Move& pl: b.getMovesPlacingSegment(s)) { constr.addVariable(to_string(pl), 1.0); } constr.setName("r1a_" + constr_name); constr.setType(Constraint::LT); constr.setBound(0.0); addConstraint(constr); } // (1b) { Constraint constr; for (Move& rm: b.getMovesRemovingSegment(s)) { constr.addVariable(to_string(rm), 1.0); } constr.setName("r1b_" + constr_name); constr.setType(Constraint::LT); constr.setBound(1.0); addConstraint(constr); } } else { // (2a) { Constraint constr; for (Move& pl: b.getMovesPlacingSegment(s)) { constr.addVariable(to_string(pl), 1.0); } constr.setName("r2a_" + constr_name); constr.setType(Constraint::LT); constr.setBound(1.0); addConstraint(constr); } // (2b) { Constraint constr; for (Move& pl: b.getMovesPlacingSegment(s)) { constr.addVariable(to_string(pl), 1.0); } for (Move& rm: b.getMovesRemovingSegment(s)) { constr.addVariable(to_string(rm), -1.0); } constr.setName("r2b_" + constr_name); constr.setType(Constraint::GT); constr.setBound(0.0); addConstraint(constr); } } } // EXTRA CONSTRAINTS: // // for each move m: // for each dot d required by m: // for each move n placing d that is consistent with m: // weight_m <= sum of weights of n's if (getFlag("extra")) { for (const Move& m: b.getMoveList()) { std::string constr_name = "_" + to_string(m); for (const Dot& d: m.requiredDots(b.getVariant())) { if (b.hasDot(d)) continue; Constraint constr; for (const Move& n: b.getMovesPlacingSegment(Segment(d,0))) { if (m.consistentWith(n,b.getVariant())) { constr.addVariable(to_string(n), -1.0); } } constr.addVariable(to_string(m), 1.0); constr.setName("extra_" + to_string(d) + constr_name); constr.setType(Constraint::LT); constr.setBound(0.0); addConstraint(constr); } } } // Disallow cycles of length 3 from the solution. // Improves fuzzy solutions if (getFlag("short-cycles")) { for (const Segment& s: b.getSegmentList()) { int d = s.second; if (d % 2 == 1) continue; addConstraints(createCycleConstraints(s, d + 2, d + 5)); addConstraints(createCycleConstraints(s, d + 6, d + 1)); } } // Constraints for acyclic problems (explanation makes sense for exact problems): // // OBSOLETE // // 1. Each move mv_* has accompanying order variable order_* // 2. Move that is not picked has always order 0, // move that is picked has order between 1 and 675 // // It is accomplished with the condition: // mv_ <= order_ <= 675 * mv_ // // 3. Assume that mv_1 removes segment s and mv_2 places segment s (mv_1 != mv_2). // Then // order_1 + (1 - mv_1) * 1000 >= order_2 + 1 // // The (1-mv_1)*1000 term assures that the condition is not enforced // for moves that are not picked (i.e. have mv_1 = 0) if (getFlag("acyclic")) { throw std::string("not implemented"); } // Constraints for symmetric problems. // // Moves that are symmetric by central symmetry // with center at ref + (1.5,1.5) have to have equal weights if (getFlag("symmetric")) { for (const Move&m: b.getMoveList()) { Move sm = b.centerSymmetry(m); Constraint c; c.addVariable(to_string(m), 1.0); c.addVariable(to_string(sm), -1.0); c.setType(Constraint::EQ); c.setBound(0.0); c.setName("sym_" + to_string(m)); addConstraint(c); } } // dot-acyclic - better implementation of acyclic problems // dots that are not placed have dot_ variable equal to 0 // this is important for --hull option // use this not only for dot-acyclic problems for (const Dot& d: b.getDotList()) { if (b.hasDot(d)) continue; Constraint c; c.setName("dotmove_" + to_string(d)); c.addVariable("dot_" + to_string(d), 1.0); for (const Move& m: b.getMovesPlacingDot(d)) { c.addVariable(to_string(m), -b.bound()); } c.setType(Constraint::LT); c.setBound(0.0); addConstraint(c); } if (getFlag("dot-acyclic")) { for (int x = 0; x < b.getWidth(); x++) { for (int y= 0; y < b.getHeight(); y++) { if (b.infeasibleDot(Dot(x,y)) || b.hasDot(Dot(x,y))) continue; setVariableBounds("dot_" + to_string(Dot(x,y)), 0, b.bound()); if (getFlag("symmetric")) { Constraint c; if (b.infeasibleDot(b.centerSymmetry(Dot(x,y)))) continue; c.setName("dotsym_"); c.addVariable("dot_" + to_string(Dot(x,y)), 1.0); c.addVariable("dot_" + to_string(b.centerSymmetry(Dot(x,y))), -1.0); c.setType(Constraint::EQ); c.setBound(0.0); addConstraint(c); } } } for (const Move& m: b.getMoveList()) { for (const Dot& rq: m.requiredDots(b.getVariant())) { if (b.hasDot(rq)) continue; Constraint c; // dot_placed >= dot_required + 1 - (1 - m) * bound // i.e. dot_placed - dot_required - bound * m >= 1 - bound c.setName("dot_"); c.addVariable("dot_" + to_string(m.placedDot()), 1.0); c.addVariable("dot_" + to_string(rq), -1.0); c.addVariable(to_string(m), -b.bound()); c.setBound(1 - b.bound()); c.setType(Constraint::GT); addConstraint(c); } } } // Constraints that enforce that the board (if it is rectangle) is // the convex hull of the solution if (getFlag("rhull")) { // right side addConstraint(getSideConstraint(1,0,true)); // left side addConstraint(getSideConstraint(1,0,false)); // top side addConstraint(getSideConstraint(0,1,true)); // bottom side addConstraint(getSideConstraint(0,1,false)); } // Constraints that enforce that the board (if it is octagon) is // the convex hull of the solution if (getFlag("hull")) { // right side addConstraint(getSideConstraint(1,0,true)); // left side addConstraint(getSideConstraint(1,0,false)); // lower right side addConstraint(getSideConstraint(1,-1,false)); // upper left side addConstraint(getSideConstraint(1,-1,true)); // top side addConstraint(getSideConstraint(0,1,true)); // bottom side addConstraint(getSideConstraint(0,1,false)); // lower left side addConstraint(getSideConstraint(1,1,false)); // upper right side addConstraint(getSideConstraint(1,1,true)); } return this; }
/** * Create a composite 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 */ CompositeFunction_sptr FunctionFactoryImpl::createComposite( const Expression &expr, std::map<std::string, std::string> &parentAttributes) const { if (expr.name() != ";") inputError(expr.str()); if (expr.size() == 0) { return CompositeFunction_sptr(); } const std::vector<Expression> &terms = expr.terms(); auto it = terms.cbegin(); const Expression &term = it->bracketsRemoved(); CompositeFunction_sptr cfun; if (term.name() == "=") { if (term.terms()[0].name() == "composite") { 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 = boost::dynamic_pointer_cast<CompositeFunction>( createFunction("CompositeFunction")); if (!cfun) inputError(expr.str()); } else { inputError(expr.str()); } } else if (term.name() == ",") { auto firstTerm = term.terms().cbegin(); if (firstTerm->name() == "=") { if (firstTerm->terms()[0].name() == "composite") { cfun = boost::dynamic_pointer_cast<CompositeFunction>( createSimple(term, parentAttributes)); if (!cfun) inputError(expr.str()); ++it; } else if (firstTerm->terms()[0].name() == "name") { cfun = boost::dynamic_pointer_cast<CompositeFunction>( createFunction("CompositeFunction")); if (!cfun) inputError(expr.str()); } else { inputError(expr.str()); } } } else if (term.name() == ";") { cfun = boost::dynamic_pointer_cast<CompositeFunction>( createFunction("CompositeFunction")); if (!cfun) inputError(expr.str()); } else { inputError(expr.str()); } if (!cfun) inputError(expr.str()); for (; it != terms.end(); ++it) { const Expression &term = it->bracketsRemoved(); IFunction_sptr fun; std::map<std::string, std::string> pAttributes; if (term.name() == ";") { fun = createComposite(term, pAttributes); if (!fun) continue; } else { std::string parName = term[0].name(); if (parName.size() >= 10 && parName.substr(0, 10) == "constraint") { addConstraints(cfun, term[1]); continue; } else if (parName == "ties") { addTies(cfun, term[1]); continue; } else { fun = createSimple(term, pAttributes); } } cfun->addFunction(fun); size_t i = cfun->nFunctions() - 1; for (auto &pAttribute : pAttributes) { // Apply parent attributes of the child function to this function. If this // function doesn't have those attributes, they get passed up the chain to // this function's parent. if (cfun->hasLocalAttribute(pAttribute.first)) { cfun->setLocalAttributeValue(i, pAttribute.first, pAttribute.second); } else { parentAttributes[pAttribute.first] = pAttribute.second; } } } if (cfun) { cfun->applyTies(); } return cfun; }
/** * Create a composite 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 */ CompositeFunction_sptr FunctionFactoryImpl::createComposite(const Expression& expr, std::map<std::string,std::string>& parentAttributes)const { if (expr.name() != ";") inputError(expr.str()); if (expr.size() == 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_sptr cfun; if (term.name() == "=") { if (term.terms()[0].name() == "composite") { 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 = boost::dynamic_pointer_cast<CompositeFunction>(createFunction("CompositeFunction")); if (!cfun) inputError(expr.str()); } else { inputError(expr.str()); } } else if (term.name() == ",") { std::vector<Expression>::const_iterator firstTerm = term.terms().begin(); if (firstTerm->name() == "=") { if (firstTerm->terms()[0].name() == "composite") { cfun = boost::dynamic_pointer_cast<CompositeFunction>(createSimple(term,parentAttributes)); if (!cfun) inputError(expr.str()); ++it; } else if (firstTerm->terms()[0].name() == "name") { cfun = boost::dynamic_pointer_cast<CompositeFunction>(createFunction("CompositeFunction")); if (!cfun) inputError(expr.str()); } else { inputError(expr.str()); } } } else if (term.name() == ";") { cfun = boost::dynamic_pointer_cast<CompositeFunction>(createFunction("CompositeFunction")); if (!cfun) inputError(expr.str()); } else { inputError(expr.str()); } for(;it!=terms.end();++it) { const Expression& term = it->bracketsRemoved(); IFunction_sptr fun; std::map<std::string,std::string> pAttributes; if (term.name() == ";") { fun = createComposite(term,pAttributes); if (!fun) continue; } else { std::string parName = term[0].name(); if (parName.size() >= 10 && parName.substr(0,10) == "constraint") { addConstraints(cfun,term[1]); continue; } else if (parName == "ties") { addTies(cfun,term[1]); continue; } else { fun = createSimple(term,pAttributes); } } cfun->addFunction(fun); size_t i = cfun->nFunctions() - 1; for(auto att = pAttributes.begin(); att != pAttributes.end(); ++att) { cfun->setLocalAttributeValue(i,att->first,att->second); } } cfun->applyTies(); return cfun; }