include/topology/image-zigzag-persistence.h
author Dmitriy Morozov <dmitriy@mrzv.org>
Mon, 06 Mar 2023 12:43:45 -0800
changeset 300 d24de31c84a6
parent 253 6dc64e820477
permissions -rw-r--r--
Disable building e/a/alphashapes2d-periodic

#ifndef __IMAGE_ZIGZAG_PERSISTENCE_H__
#define __IMAGE_ZIGZAG_PERSISTENCE_H__

#include "zigzag-persistence.h"
#include <limits>

struct SimplexSubcomplexData
{
                SimplexSubcomplexData(bool sc = false):
                    subcomplex(sc)                              {}

    bool        subcomplex;
};

template<class BirthID_ = Empty<> >
class ImageZigzagPersistence: public ZigzagPersistence<BirthID_, SimplexSubcomplexData>
{
    public:
        typedef                 BirthID_                                                    BirthID;
        typedef                 ZigzagPersistence<BirthID, SimplexSubcomplexData>           Parent;

        typedef                 typename Parent::IndexDeathPair                             IndexDeathPair;
        typedef                 typename Parent::Death                                      Death;

        typedef                 typename Parent::ZIndex                                     ZIndex;
        typedef                 typename Parent::BIndex                                     BIndex;
        typedef                 typename Parent::SimplexIndex                               SimplexIndex;
        typedef                 typename Parent::ZColumn                                    ZColumn;
        typedef                 typename Parent::BColumn                                    BColumn;
        typedef                 typename Parent::BRow                                       BRow;
        typedef                 typename Parent::CRow                                       CRow;
        typedef                 typename Parent::ZNode                                      ZNode;
        typedef                 typename Parent::BNode                                      BNode;
        typedef                 typename Parent::SimplexNode                                SimplexNode;


                                ImageZigzagPersistence():
                                    im_last(Parent::z_list.end()), cok_begin(Parent::z_list.end()),
                                    im_order_begin(std::numeric_limits<int>::min()/2),
                                    cok_order_begin(std::numeric_limits<int>::max()/2)
                                {}

        IndexDeathPair          add(ZColumn         bdry,
                                    bool            subcomplex,
                                    const BirthID&  birth = BirthID())                      { ImageZZVisitor zzv(subcomplex); return Parent::add(bdry, birth, zzv); }

        Death                   remove(SimplexIndex s, const BirthID& birth = BirthID())    { ImageZZVisitor zzv(s->subcomplex); return Parent::remove(s, birth, zzv); }


        ZIndex                  image_begin()                                               { return Parent::z_list.begin(); }
        ZIndex                  image_end()                                                 { return cok_begin; }
        BIndex                  boundary_end()                                              { return Parent::b_list.end(); }


        // Class: ImageZZVisitor
        // Contains all the tweaks to the normal zigzag algorithm to make it compute image zigzag
        class ImageZZVisitor: public Parent::ZigzagVisitor
        {
            public:
                                    ImageZZVisitor(bool sc = false):
                                        subcomplex(sc), birth_in_image(false)                   {}

                // Sets the subcomplex property of the new simplex
                SimplexIndex        new_simplex(Parent& zz);

                // Decides where to put the new column (image or cokernel)
                ZIndex              new_z_in_add(Parent& zz, const ZColumn& z, const BRow& u);

                // Checks if there is a boundary entirely in the subcomplex, and sets birth_in_image accordingly
                BIndex              select_j_in_remove(Parent& zz, const CRow& c_row);

                ZIndex              new_z_in_remove(Parent& zz);

                // Updates im_last and cok_begin if necessary
                void                erasing_z(Parent& zz, ZIndex j);

                // Determines if there is a death in the image
                Death               death(Parent& zz, ZIndex dying_z);

            private:
                ZIndex              append_in_image(Parent& zz);
                ZIndex              append_in_cokernel(Parent& zz);
                ZIndex              prepend_in_image(Parent& zz);
                ZIndex              prepend_in_cokernel(Parent& zz);
                bool                in_subcomplex(const ZColumn& z);

                bool                subcomplex, birth_in_image;
        };

        const int                   im_order_begin;
        const int                   cok_order_begin;

    private:
        using                   Parent::make_remover;
        using                   Parent::make_appender;
        using                   Parent::make_adder;

    private:
        ZIndex                  im_last;                // index of the last image cycle
        ZIndex                  cok_begin;              // index of the first cokernel cycle
};


#include "image-zigzag-persistence.hpp"

#endif