void setPartner(Cell const v, Cell const w)
    {
        pairUp(v, w);

        std::queue<Cell> q;
        if (_complex.cellDimension(v) > _complex.cellDimension(w))
            q.push(v);
        else
            q.push(w);

        while (not q.empty())
        {
            Cell const cell = q.front();
            q.pop();

            for (size_t i = 0; i < _coI.count(cell); ++i)
            {
                Cell const cof = _coI(cell, i);
                if (_nrPairableFacets.at(cof) != 1)
                    continue;
                for (size_t j = 0; j < _I.count(cof); ++j)
                {
                    Cell const f = _I(cof, j);
                    if (!_field.getDirection(f))
                    {
                        pairUp(cof, f);
                        q.push(cof);
                        q.push(f);
                        break;
                    }
                }
            }
        }
    }
 SmartMorseVectorField(CubicalComplex const& complex)
 : _complex(complex),
   _I(complex.xdim(), complex.ydim(), complex.zdim(), false),
   _coI(complex.xdim(), complex.ydim(), complex.zdim(), true),
   _field(complex),
   _nrPairableFacets(complex.cellIdLimit())
 {
     for (Cell cell = 0; cell < complex.cellIdLimit(); ++cell)
         if (complex.isCell(cell))
             _nrPairableFacets.at(cell) = _I.count(cell);
 }
Exemple #3
0
bool isLocalMinimum(
    Cell const v,
    Facets const& I,
    Facets const& coI,
    Scalars const& scalars)
{
    float const h = scalars(v);

    size_t const m = I.count(v);
    for (size_t i = 0; i < m; ++i)
    {
        Cell const e = I(v, i);
        size_t const k = coI.count(e);
        for (size_t j = 0; j < k; ++j)
        {
            Cell const w = coI(e, j);
            if (w != v and scalars(w) <= h)
                return false;
        }
    }

    return true;
}
bool isLocalMinimum(
    Cell const v,
    Facets const& I,
    Facets const& coI,
    Vertices const& vertices,
    Scalars const& scalars)
{
    float const h = cellAverage(v, scalars, vertices);

    size_t const m = I.count(v);
    for (size_t i = 0; i < m; ++i)
    {
        Cell const e = I(v, i);
        size_t const k = coI.count(e);
        for (size_t j = 0; j < k; ++j)
        {
            Cell const w = coI(e, j);
            if (w != v and cellAverage(w, scalars, vertices) <= h)
                return false;
        }
    }

    return true;
}
VolumeData withSaturatedVectorField(VolumeData const& original)
{
    CubicalComplex const& complex = original.complex;
    Facets const facets(complex.xdim(), complex.ydim(), complex.zdim(), false);

    Field::DataPtr const& oldData = original.field.data();
    Field::DataPtr newData(new Field::DataPtr::element_type(*oldData));
    Field field(complex.xdim(), complex.ydim(), complex.zdim(), newData);

    for (Cell start = 0; start < complex.cellIdLimit(); ++start)
    {
        if (not complex.isCell(start) or not field.isCritical(start))
            continue;
        int const n = facets.count(start);
        for (int i = 0; i < n; ++i)
        {
            Cell const f = facets(start, i);
            if (field.isCritical(f))
                field.setPartner(start, f);
        }
    }

    return VolumeData(complex, original.scalars, field);
}
    void extract(
        Cell const v,
        Facets const& cofacets,
        Vertices const& vertices,
        Scalars const& scalars)
    {
        Value value = scalars.get(v);

        cells_[0] = v;
        defined_[0] = false;
        weight_[0] = value;
        ranked_[0] = 0;
        incidence_counts_[0] = 0;
        size_ = 1;

        int mark = size_;
        int next = 0;
        while (next < size_)
        {
            Cell const cell = cells_[next];

            int const n = cofacets.count(cell);

            for (int i = n - 1; i >= 0; --i)
            {
                Cell const coface = cofacets(cell, i);
                int k;
                for (k = mark; k < size_; ++k)
                    if (coface == cells_[k])
                        break;
                if (k < size_)
                {
                    incidences_[k][incidence_counts_[k]] = next;
                    ++incidence_counts_[k];
                    continue;
                }

                int const m = vertices.count(coface);
                bool add = true;
                Value sum = 0.0;
                for (int j = 0; j < m; ++j)
                {
                    Cell const w = vertices(coface, j);
                    Value const d = scalars.get(w);
                    if (d > value or (d == value and w > v))
                    {
                        add = false;
                        break;
                    }
                    sum += d;
                }

                if (add)
                {
                    cells_[size_] = coface;
                    defined_[size_] = false;
                    weight_[size_] = sum;
                    ranked_[size_] = size_;
                    incidences_[size_][0] = next;
                    incidence_counts_[size_] = 1;
                    ++size_;

                    if (size_ > MAX_STAR)
                        throw starException;
                }
            }

            ++next;
            if (next == mark)
                mark = size_;
        }

        for (int i = 0; i < size_; ++i) {
            int j;
            Value x = weight_[i];
            for (j = i; j > 0 && x < weight_[j-1]; --j) {
                ranked_[j] = ranked_[j-1];
                weight_[j] = weight_[j-1];
            }
            ranked_[j] = i;
            weight_[j] = x;
        }
    }
 void update(Cell const v)
 {
     _nrPairableFacets.at(v) = 0;
     for (size_t i = 0; i < _coI.count(v); ++i)
         --_nrPairableFacets.at(_coI(v, i));
 }
Result checkConnections(VolumeData const& candidate)
{
    CubicalComplex const& complex = candidate.complex;
    Field const& field = candidate.field;

    Field::Vectors const V = field.V();
    Field::Vectors const coV = field.coV();
    Facets const I(complex.xdim(), complex.ydim(), complex.zdim(), false);
    Facets const coI(complex.xdim(), complex.ydim(), complex.zdim(), true);

    std::vector<Cell> const sources = criticalCells(candidate);

    std::shared_ptr<std::vector<bool> > marked =
        connectingPaths(complex, field, V, coV, I, coI);

    for (size_t v = 0; v < complex.cellIdLimit(); ++v)
    {
        if (not marked->at(v))
        {
            if (complex.isCell(v) and field.isCritical(v))
            {
                std::stringstream msg;
                msg << "unmarked critical cell at " << complex.cellPosition(v);
                return failure(msg.str());
            }
        }
        else
        {
            bool good = false;

            if (field.isCritical(v))
            {
                continue;
            }
            else if (V.defined(v))
            {
                Cell const u = V(v);
                for (int i = 0; i < coI.count(v); ++i)
                {
                    Cell const w = coI(v, i);
                    good = good || (w != u and marked->at(w));
                }
            }
            else
            {
                Cell const u = coV(v);
                for (int i = 0; i < I.count(v); ++i)
                {
                    Cell const w = I(v, i);
                    good = good || (w != u and marked->at(w));
                }
            }

            if (not good)
            {
                std::stringstream msg;
                msg << "dead end at " << complex.cellPosition(v);
                return failure(msg.str());
            }
        }
    }

    return success();
}