Example #1
0
Distribution combine(Distribution const& c, InfoMap const& info)
{
    std::map<Cell, Value> tmp;

    for (size_t i = 0; i < c.size(); ++i)
    {
        Distribution const& w = info(c.at(i).first)->weights;
        Value const f = c.at(i).second;

        for (size_t j = 0; j < w.size(); ++j)
        {
            Cell const v = w.at(j).first;
            if (tmp.count(v) == 0)
                tmp[v] = 0;
            tmp[v] += f * w.at(j).second;
        }
    }

    Distribution result(tmp.size());

    std::map<Cell, Value>::const_iterator iter = tmp.begin();
    for (size_t i = 0; i < tmp.size(); ++i, ++iter)
        result[i] = std::make_pair(iter->first, iter->second);

    return result;
}
Example #2
0
Mask boundaries(
    CubicalComplex const& complex,
    Scalars const& scalars)
{
    Facets I(complex.xdim(), complex.ydim(), complex.zdim(), false);
    Facets coI(complex.xdim(), complex.ydim(), complex.zdim(), true);
    VertexQueue queue;
    InfoMap info(complex);
    Mask result(complex);

    for (Cell v = 0; v < complex.cellIdLimit(); ++v)
    {
        if (complex.isCell(v) and complex.cellDimension(v) == 0 and 
            isLocalMinimum(v, coI, I, scalars))
        {
            queue.push(v, scalars(v) + 1);
            info.set(v, InfoPtr(new VertexInfo()));
            result.set(v, 2);
        }
    }

    while (not queue.empty())
    {
        Cell const v = queue.top();
        queue.pop();

        size_t const m = coI.count(v);
        std::vector<size_t> lower;
        for (size_t i = 0; i < m; ++i)
        {
            Cell const w = opposite(coI(v, i), v, I);
            if (not info(w))
            {
                queue.push(w, scalars(w));
                info.set(w, InfoPtr(new VertexInfo()));
            }
            else if (info(w)->active)
                lower.push_back(w);
        }

        info(v)->active = true;
        info(v)->countDown = m - lower.size();

        if (lower.size() == 0)
        {
            info(v)->weights = Distribution(1);
            info(v)->weights.at(0) = std::make_pair(v, 1);
            info(v)->basin = v;
        }
        else
        {
            Distribution const dist =
                derivedDistribution(v, lower, info, scalars);
            info(v)->weights = dist;

            std::set<size_t> seen;
            for (size_t i = 0; i < lower.size(); ++i)
                seen.insert(info(lower.at(i))->basin);

            std::pair<size_t, Value> best;
            size_t count = 0;
            for (size_t i = 0; i < dist.size(); ++i)
                if (seen.count(dist.at(i).first) > 0)
                    if (++count == 1 or dist.at(i).second > best.second)
                        best = dist.at(i);

            info(v)->basin = best.first;
        }

        for (size_t i = 0; i < lower.size(); ++i)
        {
            Cell const w = lower.at(i);
            if (info(v)->basin != info(w)->basin and scalars(v) <= 0)
                result.set(std::min(v, w), 1);

            if (--(info(w)->countDown) == 0)
                info.set(w, InfoPtr());
        }
    }

    return result;
}