Skip to content

Commit

Permalink
#212 Optimize apply_reaction_rules
Browse files Browse the repository at this point in the history
  • Loading branch information
kaizu committed Dec 21, 2017
1 parent 6b353e7 commit 741faa5
Show file tree
Hide file tree
Showing 3 changed files with 476 additions and 21 deletions.
130 changes: 109 additions & 21 deletions ecell4/core/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,13 +394,13 @@ std::vector<DummyReactionRule> generate_reaction_rules(
reactants[1] = sp2;
std::vector<DummyReactionRule> res = org.generate(reactants);

if (org.reactants()[0] != org.reactants()[1])
{
reactants[0] = sp2;
reactants[1] = sp1;
std::vector<DummyReactionRule> _res = org.generate(reactants);
std::copy(_res.begin(), _res.end(), back_inserter(res));
}
// if (org.reactants()[0] != org.reactants()[1])
// {
// reactants[0] = sp2;
// reactants[1] = sp1;
// std::vector<DummyReactionRule> _res = org.generate(reactants);
// std::copy(_res.begin(), _res.end(), back_inserter(res));
// }
return res;
}

Expand Down Expand Up @@ -469,12 +469,63 @@ void __apply_reaction_rules(
const std::vector<DummyReactionRule>& rules,
std::vector<DummyReactionRule>& reactions,
std::vector<Dummy>& allseeds,
const std::map<Dummy, Integer>& max_stoich)
const std::map<Dummy, Integer>& max_stoich,
std::vector<std::vector<std::vector<Dummy>::size_type> >& candidates)
{
allseeds.insert(allseeds.begin(), seeds.begin(), seeds.end());
std::vector<Dummy>::size_type stride = allseeds.size();

std::vector<std::vector<std::vector<Dummy>::size_type> >::size_type count = 0;
for (std::vector<DummyReactionRule>::const_iterator
i(rules.begin()); i != rules.end(); ++i)
{
const DummyReactionRule& rr(*i);

switch (rr.reactants().size())
{
case 0:
continue;
case 1:
continue;
case 2:
{
if (candidates.size() < count + 2 + 1)
{
candidates.resize(count + 2 + 1);
}

SpeciesExpressionMatcher reactant0(rr.reactants()[0].units());
SpeciesExpressionMatcher reactant1(rr.reactants()[1].units());

std::vector<Dummy>::size_type idx = stride;
for (std::vector<Dummy>::const_iterator j(seeds.begin());
j != seeds.end(); ++j, ++idx)
{
if (reactant0.match((*j).units()))
{
candidates[count].push_back(idx);
}
if (reactant1.match((*j).units()))
{
candidates[count + 1].push_back(idx);
}
}
count += 2;
}
break;
default:
throw NotImplemented(
"No reaction rule with more than two reactants is accepted.");
}
}

// allseeds.insert(allseeds.begin(), seeds.begin(), seeds.end());
allseeds.insert(allseeds.end(), seeds.begin(), seeds.end());

std::vector<Dummy> newseeds;

// std::cout << "Start Generations: " << stride << ", " << seeds.size() << std::endl;

count = 0;
for (std::vector<DummyReactionRule>::const_iterator
i(rules.begin()); i != rules.end(); ++i)
{
Expand All @@ -494,20 +545,50 @@ void __apply_reaction_rules(
}
break;
case 2:
for (std::vector<Dummy>::const_iterator j(seeds.begin());
j != seeds.end(); ++j)
{
const std::vector<Dummy>::const_iterator start(
allseeds.begin()
+ std::distance<std::vector<Dummy>::const_iterator>(
seeds.begin(), j));
for (std::vector<Dummy>::const_iterator
k(start); k != allseeds.end(); ++k)
for (std::vector<std::vector<Dummy>::size_type>::const_iterator j(candidates[count].begin());
j != candidates[count].end(); ++j)
{
__add_reaction_rules(
generate_reaction_rules(rr, *j, *k),
reactions, newseeds, allseeds, max_stoich);
for (std::vector<std::vector<Dummy>::size_type>::const_iterator k(candidates[count + 1].begin());
k != candidates[count + 1].end(); ++k)
{
// std::cout << "Reaction [" << count << "]: " << (*j) << ", " << (*k) << std::endl;

if ((*j) < stride && (*k) < stride)
{
continue;
}

// std::cout << "Generate Reaction [" << count << ":" << rr.data.as_string() << "]: ";

const Dummy& reactant0(allseeds[(*j)]);
const Dummy& reactant1(allseeds[(*k)]);

// std::cout << reactant0.serial() << " + " << reactant1.serial() << std::endl;

__add_reaction_rules(
generate_reaction_rules(rr, reactant0, reactant1),
reactions, newseeds, allseeds, max_stoich);
}
}

// for (std::vector<Dummy>::const_iterator j(seeds.begin());
// j != seeds.end(); ++j)
// {
// const std::vector<Dummy>::const_iterator start(
// allseeds.begin()
// + std::distance<std::vector<Dummy>::const_iterator>(
// seeds.begin(), j));
// for (std::vector<Dummy>::const_iterator
// k(start); k != allseeds.end(); ++k)
// {
// __add_reaction_rules(
// generate_reaction_rules(rr, *j, *k),
// reactions, newseeds, allseeds, max_stoich);
// }
// }

count += 2;
}
break;
default:
Expand All @@ -516,6 +597,11 @@ void __apply_reaction_rules(
}
}

// for (std::vector<Dummy>::const_iterator j(newseeds.begin());
// j != newseeds.end(); ++j)
// {
// std::cout << "NEW: " << (*j).serial() << std::endl;
// }
seeds.swap(newseeds);
}

Expand Down Expand Up @@ -558,10 +644,12 @@ std::pair<std::vector<ReactionRule>, bool> apply_reaction_rules(
}

{
std::vector<std::vector<std::vector<Dummy>::size_type> > _candidates;

Integer iteration_count(0);
while (_seeds.size() > 0 && iteration_count < max_itr)
{
__apply_reaction_rules(_seeds, _rules, _reactions, _allseeds, _max_stoich);
__apply_reaction_rules(_seeds, _rules, _reactions, _allseeds, _max_stoich, _candidates);
iteration_count += 1;
}
}
Expand Down
208 changes: 208 additions & 0 deletions ecell4/core/Context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,214 @@ struct DummyBinder
}
};

// template <typename Element>
// class MultiSpeciesMatcher
// {
// public:
//
// typedef Element element_type;
//
// typedef MatchObject::context_type context_type;
// typedef std::vector<element_type> element_container_type;
//
// public:
//
// MultiSpeciesMatcher(const element_container_type& patterns)
// : patterns_(patterns)
// {
// ;
// }
//
// virtual ~MultiSpeciesMatcher()
// {
// ;
// }
//
// bool match(const element_type& sp)
// {
// element_container_type targets;
// targets.push_back(sp);
// return __match(targets);
// }
//
// bool match(const element_type& sp1, const element_type& sp2)
// {
// element_container_type targets;
// targets.push_back(sp1);
// targets.push_back(sp2);
// return __match(targets);
// }
//
// bool match(const element_container_type& targets)
// {
// return __match(targets);
// }
//
// bool __match(const element_container_type& targets)
// {
// if (patterns_.size() != targets.size())
// {
// return false;
// }
//
// matchers_.clear();
// for (typename element_container_type::const_iterator
// i(patterns_.begin()); i != patterns_.end(); ++i)
// {
// matchers_.push_back(SpeciesExpressionMatcher((*i).units()));
// }
//
// targets_ = targets; //XXX: copy?
// itr_ = matchers_.begin();
// context_type::variable_container_type globals;
// return __submatch(globals);
// }
//
// bool __submatch(const context_type::variable_container_type& globals)
// {
// if (itr_ == matchers_.end())
// {
// return true;
// }
//
// bool retval((*itr_).match(
// targets_[std::distance(matchers_.begin(), itr_)].units(),
// globals));
// while (retval)
// {
// const context_type::variable_container_type&
// globals_prev((*itr_).context().globals);
// ++itr_;
// const bool succeeded(__submatch(globals_prev));
// if (succeeded)
// {
// return true;
// }
// --itr_;
// retval = (*itr_).next();
// }
// return false;
// }
//
// bool next()
// {
// if (itr_ != matchers_.end() || patterns_.size() == 0)
// {
// return false;
// }
// else if (matchers_.size() == 0)
// {
// return true;
// }
//
// do
// {
// --itr_;
// bool retval((*itr_).next());
// while (retval)
// {
// const context_type::variable_container_type&
// globals_prev((*itr_).context().globals);
// ++itr_;
// const bool succeeded(__submatch(globals_prev));
// if (succeeded)
// {
// return true;
// }
// --itr_;
// retval = (*itr_).next();
// }
// }
// while (itr_ != matchers_.begin());
// return false;
// }
//
// std::pair<bool, context_type> __match(
// const context_type::variable_container_type& globals,
// typename element_container_type::const_iterator i,
// typename element_container_type::const_iterator j)
// {
// SpeciesExpressionMatcher m((*i).units());
// if (!m.match(*j, globals))
// {
// return std::make_pair(false, context_type());
// }
//
// ++i;
// ++j;
// if (i == patterns_.end() || j == targets_.end())
// {
// return std::make_pair(true, m.context());
// }
//
// do
// {
// if (__match(m.context().globals, i, j).first)
// {
// return std::make_pair(true, m.context());
// }
// } while (m.next());
// return std::make_pair(false, context_type());
// }
//
// context_type context() const
// {
// context_type ctx;
// if (matchers_.size() == 0)
// {
// return ctx;
// }
//
// ctx.globals = matchers_.back().context().globals;
//
// std::vector<unsigned int> strides;
// strides.reserve(targets_.size());
// {
// unsigned int stride = 0;
// for (typename element_container_type::const_iterator
// i(targets_.begin()); i != targets_.end(); ++i)
// {
// strides.push_back(stride);
// stride += (*i).units().size();
// }
// }
//
// for (std::vector<SpeciesExpressionMatcher>::const_iterator
// i(matchers_.begin()); i != matchers_.end(); ++i)
// {
// const unsigned int idx1 = std::distance(matchers_.begin(), i); // a position in matcher_
// // const unsigned int idx2 = permutation_[idx1]; // a position in targets
// const unsigned int idx2 = idx1; // a position in targets
// const unsigned int stride = strides[idx2];
//
// for (context_type::iterator_container_type::const_iterator
// j((*i).context().iterators.begin());
// j != (*i).context().iterators.end(); ++j)
// {
// // const unsigned int idx3 = std::distance((*i).context().iterators.begin(), j); // a position in context.iterators
// const unsigned int idx4 = (*j); // a position in units of a Species
//
// ctx.iterators.push_back(idx4 + stride);
// }
// }
//
// return ctx;
// }
//
// const element_container_type& targets() const
// {
// return targets_;
// }
//
// protected:
//
// const element_container_type& patterns_;
// element_container_type targets_;
//
// std::vector<SpeciesExpressionMatcher> matchers_;
// std::vector<SpeciesExpressionMatcher>::iterator itr_;
// };

template <typename Element>
class ReactionRuleExpressionMatcher
{
Expand Down
Loading

0 comments on commit 741faa5

Please sign in to comment.