bool Recurrence::calcIteratedUpdate(const UpdateMap &oldUpdate, const Expression &meterfunc, UpdateMap &newUpdate) { assert(newUpdate.empty()); UpdateMap update = oldUpdate; //might be changed by dependencyOrder, so copy here vector<VariableIndex> order = dependencyOrder(update); assert(order.size() == update.size()); //in the given order try to solve the recurrence for every updated variable for (VariableIndex vi : order) { Expression res; ExprSymbol target = itrs.getGinacSymbol(vi); //use update rhs, but replace already processed variables with their recurrences Expression todo = update.at(vi).subs(knownPreRecurrences); if (!findUpdateRecurrence(todo,target,res)) { return false; } //remember this recurrence to replace vi in the updates depending on vi //note that updates need the value at n-1, e.g. x(n) = x(n-1) + vi(n-1) for the update x=x+vi knownPreRecurrences[target] = res.subs(ginacN == ginacN-1); //calcuate the final update using the loop's runtime newUpdate[vi] = res.subs(ginacN == meterfunc); } return true; }
bool MultiFormMgr::Paint(bool fForceBackBufferValid) { // Calc opaque rect Rect rcOpaque; rcOpaque.SetEmpty(); CalcOpaqueRect(NULL, NULL, &rcOpaque); bool fAnyScroll = false; int n; for (n = 0; n < m_cfrmm; n++) { // Paint children form mgr bits bool fScrolled = m_apfrmm[n]->ScrollBits(); if (fForceBackBufferValid) fScrolled = true; if (fScrolled) fAnyScroll = true; // Paint / calc updatemaps for children Rect rcT; rcT.Intersect(&m_arcFormMgr[n], &rcOpaque); rcT.Offset(-m_arcFormMgr[n].left, -m_arcFormMgr[n].top); m_apfrmm[n]->Paint(fScrolled, &rcT); } // There is a form, need the children updatemap data to be reflected in the // parent updatemap for (n = 0; n < m_cfrmm; n++) { FormMgr *pfrmm = m_apfrmm[n]; UpdateMap *pupd = pfrmm->GetUpdateMap(); Rect rcT; bool fFirst = true; while (pupd->EnumUpdateRects(fFirst, NULL, &rcT)) { fFirst = false; rcT.Offset(m_arcFormMgr[n].left, m_arcFormMgr[n].top); m_pupd->InvalidateRect(&rcT); } } // Now that the multi-form mgr has all the invalid state reflected, // it is ok to paint rcOpaque.SetEmpty(); FormMgr::Paint(false, &rcOpaque); return fAnyScroll; }
int MultiFormMgr::GetUpdateRectCount() { int c = 0; for (int n = 0; n < m_cfrmm; n++) { UpdateMap *pupd = m_apfrmm[n]->GetUpdateMap(); Size sizMap; pupd->GetMapSize(&sizMap); int cb = sizMap.cx * sizMap.cy; bool *pfInvalid = pupd->GetInvalidMap(); while (cb-- != 0) { if (*pfInvalid++) c++; } } return c; }
//NOTE: very stupid and not very efficient; better use a graph for this problem vector<VariableIndex> Recurrence::dependencyOrder(UpdateMap &update) { vector<VariableIndex> ordering; set<VariableIndex> orderedVars; while (ordering.size() < update.size()) { bool changed = false; for (auto up : update) { if (orderedVars.count(up.first) > 0) continue; //check if all variables on update rhs are already processed for (const string &varname : up.second.getVariableNames()) { VariableIndex vi = itrs.getVarindex(varname); if (vi != up.first && update.count(vi) > 0 && orderedVars.count(vi) == 0) goto skipUpdate; } orderedVars.insert(up.first); ordering.push_back(up.first); changed = true; skipUpdate: ; } if (changed) continue; //if not all dependencies could be resolved, try to add constraints to the guard to make things easier GiNaC::exmap subs; ExprSymbol target; bool has_target = false; for (auto up : update) { if (orderedVars.count(up.first) > 0) continue; if (!has_target) { target = itrs.getGinacSymbol(up.first); has_target = true; } else { addGuard.push_back(target == itrs.getGinacSymbol(up.first)); subs[itrs.getGinacSymbol(up.first)] = target; } } //assume all remaining variables are equal for (auto &up : update) { up.second = up.second.subs(subs); } } return ordering; }
void Union::updateModel(const UpdateMap &mapIn) { setFailure(); //assume failure until success. try { if ( mapIn.count(InputTypes::target) != 1 || mapIn.count(InputTypes::tool) < 1 ) { //we should have a status message in the base class. std::ostringstream stream; stream << "wrong number of arguments. " << "target count is: " << mapIn.count(InputTypes::target) << " " << "tool count is: " << mapIn.count(InputTypes::tool); throw std::runtime_error(stream.str()); } //target const SeerShape &targetSeerShape = mapIn.equal_range(InputTypes::target).first->second->getSeerShape(); assert(!targetSeerShape.isNull()); //tools gu::ShapeVector toolOCCTShapes; for (auto pairIt = mapIn.equal_range(InputTypes::tool); pairIt.first != pairIt.second; ++pairIt.first) { const SeerShape &toolSeerShape = pairIt.first->second->getSeerShape(); assert(!toolSeerShape.isNull()); toolOCCTShapes.push_back(toolSeerShape.getRootOCCTShape()); } //set default on failure to parent target. seerShape->partialAssign(targetSeerShape); BooleanOperation fuser(targetSeerShape.getRootOCCTShape(), toolOCCTShapes, BOPAlgo_FUSE); fuser.Build(); if (!fuser.IsDone()) throw std::runtime_error("OCC fuse failed"); ShapeCheck check(fuser.Shape()); if (!check.isValid()) throw std::runtime_error("shapeCheck failed"); seerShape->setOCCTShape(fuser.Shape()); seerShape->shapeMatch(targetSeerShape); for (auto pairIt = mapIn.equal_range(InputTypes::tool); pairIt.first != pairIt.second; ++pairIt.first) seerShape->shapeMatch(pairIt.first->second->getSeerShape()); seerShape->uniqueTypeMatch(targetSeerShape); BooleanIdMapper idMapper(mapIn, fuser.getBuilder(), iMapWrapper, seerShape.get()); idMapper.go(); seerShape->outerWireMatch(targetSeerShape); for (auto pairIt = mapIn.equal_range(InputTypes::tool); pairIt.first != pairIt.second; ++pairIt.first) seerShape->outerWireMatch(pairIt.first->second->getSeerShape()); seerShape->derivedMatch(); seerShape->dumpNils(getTypeString()); //only if there are shapes with nil ids. seerShape->dumpDuplicates(getTypeString()); seerShape->ensureNoNils(); seerShape->ensureNoDuplicates(); setSuccess(); } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); std::cout << std::endl << "Error in union update. " << e->GetMessageString() << std::endl; } catch (std::exception &e) { std::cout << std::endl << "Error in union update. " << e.what() << std::endl; } setModelClean(); }