示例#1
0
def test_nested_boundary_simplicialcomplex():
    sigma = SimplicialComplex()
    sigma.add_simplex_fromfile('test_simplexfromfile.txt')

    for k in xrange(sigma.maxK + 1):
        print str(k) + '-th Chain group:'
        for k_sim in sigma.get_allkth_simplices(k):
            delta_k = Boundary()
            delta_k.compute_boundary(k_sim)
            print 'Boundary of: ', str(k_sim), ': ', str(delta_k)
示例#2
0
def test_nested_boundary_simplicialcomplex():
    sigma = SimplicialComplex()
    sigma.add_simplex_fromfile('test_simplexfromfile.txt')

    for k in range(sigma.maxK + 1):
        print str(k) + '-th Chain group:'
        for k_sim in sigma.get_allkth_simplices(k):
            delta_k = Boundary()
            delta_k.compute_boundary(k_sim)
            print 'Boundary of: ', str(k_sim), ': ', str(delta_k)
示例#3
0
def test_nested_boundary():
    delta_k = Boundary()
    delta_k.compute_boundary(KSimplex([1, 2, 3]))
    print delta_k
    for sign, kmin1_simpl in delta_k.get_boundary():
        # print kmin1_simpl.k
        delta_kmin1 = Boundary()
        delta_kmin1.compute_boundary(kmin1_simpl)
        print delta_kmin1
示例#4
0
def test_nested_boundary():
    delta_k = Boundary()
    delta_k.compute_boundary(KSimplex([1, 2, 3]))
    print delta_k
    for sign, kmin1_simpl in delta_k.get_boundary():
        # print kmin1_simpl.k
        delta_kmin1 = Boundary()
        delta_kmin1.compute_boundary(kmin1_simpl)
        print delta_kmin1
    def compute(self):
        """
        Compute the persistent cohomology
        """
        unmarked = {}  # key = card value = list [] of unmarked simplices' id of that cardinality
        unmarked_basis = {}  # key = id, value = set of ids whose linear combination makes the basis

        for sigma in self.filtration_ar:
            if sigma.k == 0:  # Vertices
                list_of_unmarked = unmarked.get(sigma.k + 1, [])
                if list_of_unmarked:
                    if sigma.id not in unmarked[sigma.k + 1]:
                        unmarked[sigma.k + 1].append(sigma.id)  # avoid repeatedly storing an id
                        unmarked_basis[sigma.id] = {sigma.id}
                else:
                    unmarked[sigma.k + 1] = [sigma.id]
                    unmarked_basis[sigma.id] = {sigma.id}


            else:
                destroyer_flag = False
                most_recently_killed_degree = -1
                most_recently_killed_id = -1
                list_bases_toupdate = []  # list of id whose bases needs update
                boundary_obj = Boundary()
                # list_of_unmarked = []

                boundary_set = set([])
                card_boundary = sigma.k
                for sign, boundary in boundary_obj.compute_boundary(sigma):
                    # constuct string repr of the simplex
                    boundary_str = '|'.join([str(b) for b in boundary.kvertices])
                    id_boundary = getId(boundary_str)
                    boundary_set = boundary_set.union([id_boundary])

                # for each simplex of cardinality card_boundary, check whether
                # the corresponding boundary set intersection is empty or have even cardinality
                for id_sigma in unmarked.get(card_boundary, []):
                    basis_sigma = unmarked_basis.get(id_sigma)
                    intersecting_set = basis_sigma.intersection(boundary_set)
                    len_intersecting_set = len(intersecting_set)
                    if len_intersecting_set % 2:  # odd => destroyer
                        destroyer_flag = True
                        list_bases_toupdate.append(id_sigma)
                        deg_id_sigma = self.filtration_ar[self.simplexid_to_indexmap[id_sigma]].degree
                        if deg_id_sigma > most_recently_killed_degree:
                            most_recently_killed_id = id_sigma
                            most_recently_killed_degree = deg_id_sigma
                        # else:
                        #     # When both id_sigma and most_recently_killed_id have same degree, we resolve the ordering
                        #     # by their index in the filtration_ar
                        #     if self.simplexid_to_indexmap[id_sigma] > self.simplexid_to_indexmap[
                        #         most_recently_killed_id] and deg_id_sigma == most_recently_killed_degree:
                        #         most_recently_killed_id = id_sigma
                        #         most_recently_killed_degree = deg_id_sigma

                # If it is a destroyer simplex/ -ve simplex.
                if destroyer_flag:
                    birth = most_recently_killed_degree
                    death = sigma.degree
                    simplex_index = self.simplexid_to_indexmap[most_recently_killed_id]
                    simplex_to_destroy = self.filtration_ar[simplex_index]
                    assert isinstance(simplex_to_destroy, KSimplex)
                    dim = simplex_to_destroy.k
                    self.intervals[dim].append((birth, death))


                    # mark this id. we only keep unmarked ids, unmarked == pivot
                    unmarked[dim + 1].remove(most_recently_killed_id)


                    # update the bases for all ids in list_bases_toupdate except most_recently_killed_id
                    for id in list_bases_toupdate:
                        if id != most_recently_killed_id:
                            unmarked_basis[id].symmetric_difference_update(unmarked_basis[most_recently_killed_id])

                    del unmarked_basis[most_recently_killed_id]

                    unmarked_basis[sigma.id] = {sigma.id}

                else:  # New cocycle. A +ve simplex/creator.
                    list_of_unmarked = unmarked.get(sigma.k + 1, [])
                    if list_of_unmarked:
                        if sigma.id not in unmarked[sigma.k + 1]:
                            unmarked[sigma.k + 1].append(sigma.id)
                            unmarked_basis[sigma.id] = {sigma.id}
                    else:
                        unmarked[sigma.k + 1] = [sigma.id]
                        unmarked_basis[sigma.id] = {sigma.id}


        for card in unmarked.keys():
            for id_sigma in unmarked.get(card, []):
                birth = self.filtration_ar[self.simplexid_to_indexmap[id_sigma]].degree
                death = INF
                self.intervals[card - 1].append((birth, death))
示例#6
0
def test_boundary_op():
    delta = Boundary()
    delta.compute_boundary(KSimplex([1, 2, 3]))
    print delta
示例#7
0
def compute_cohomology(value=None):
    id_to_degree_map = {}  # key = id, value = filtration appearence/degree.
    cardinalities = {}
    unmarked = {
    }  # key = card value = list [] of unmarked simplices of that cardinality
    unmarked_basis = {}  # key = id, value = set of ids

    try:
        while True:
            if value is None:
                value = (yield (-1, -1, -1))

            birth = death = value.degree  # since, we ignore such cases typically.
            dim = value.k
            # Though theoretically its not the right thing to do.
            try:
                if value.k < 0:  # meaning i want to just go throw indices for infinity intervals
                    flag = False
                    for card in unmarked.keys():
                        for id_sigma in unmarked.get(card, []):
                            birth = id_to_degree_map[id_sigma]
                            death = INF
                            flag = True
                            value = (yield (birth, death, card - 1))
                            unmarked[card].remove(id_sigma)

                    if flag is False:
                        yield (-1, -1, -1)

                elif value.k == 0:  # Vertices
                    cardinalities[value.id] = value.k + 1
                    id_to_degree_map[value.id] = value.degree

                    list_of_unmarked = unmarked.get(value.k + 1, [])
                    if list_of_unmarked:
                        unmarked[value.k + 1].append(value.id)
                    else:
                        unmarked[value.k + 1] = [value.id]

                    unmarked_basis[value.id] = set([value.id])
                    value = (yield (birth, death, dim))

                else:  # 1-simplex, 2-simplex, etc.
                    destroyer_flag = False
                    most_recently_killed_degree = -1
                    most_recently_killed_id = -1
                    list_bases_toupdate = [
                    ]  # list of id whose bases needs update
                    boundary_obj = Boundary()
                    # list_of_unmarked = []

                    boundary_set = set([])
                    card_boundary = value.k
                    for sign, boundary in boundary_obj.compute_boundary(value):
                        # constuct string repr of the simplex
                        boundary_str = '|'.join(
                            [str(b) for b in boundary.kvertices])
                        id_boundary = getId(boundary_str)
                        boundary_set = boundary_set.union([id_boundary])

                    # for each simplex of cardinality card_boundary, check whether
                    # the corresponding boundary set intersection is empty or have cardinality even
                    for id_sigma in unmarked.get(card_boundary, []):
                        basis_sigma = unmarked_basis.get(id_sigma)
                        intersecting_set = basis_sigma.intersection(
                            boundary_set)
                        len_intersecting_set = len(intersecting_set)
                        if len_intersecting_set % 2:  # odd => destroyer
                            destroyer_flag = True
                            list_bases_toupdate.append(id_sigma)
                            if id_to_degree_map[
                                    id_sigma] > most_recently_killed_degree:
                                most_recently_killed_id = id_sigma
                                most_recently_killed_degree = id_to_degree_map[
                                    id_sigma]

                    # If it is a destroyer simplex/ -ve simplex.
                    if destroyer_flag:
                        birth = most_recently_killed_degree
                        death = value.degree
                        dim = cardinalities[most_recently_killed_id] - 1

                        unmarked[dim + 1].remove(most_recently_killed_id)

                        # update the bases for all ids in list_bases_toupdate except most_recently_killed_id
                        for id in list_bases_toupdate:
                            if id != most_recently_killed_id:
                                unmarked_basis[id].symmetric_difference_update(
                                    unmarked_basis[most_recently_killed_id])

                        del unmarked_basis[most_recently_killed_id]

                        unmarked_basis[value.id] = set([value.id])
                        id_to_degree_map[value.id] = value.degree

                        value = (yield (birth, death, dim))

                    else:  # New cocycle. A +ve simplex/creator.
                        cardinalities[value.id] = value.k + 1

                        list_of_unmarked = unmarked.get(value.k + 1, [])
                        if list_of_unmarked:
                            unmarked[value.k + 1].append(value.id)
                        else:
                            unmarked[value.k + 1] = [value.id]

                        unmarked_basis[value.id] = set([value.id])
                        id_to_degree_map[value.id] = value.degree

                        value = (yield (birth, death, dim))

                        # we must add the basis for value.id irrespective of it being creator or destroyer

            except Exception, e:
                value = e
    finally:
        # print "Don't forget to clean up when 'close()' is called."
        # del indices
        del id_to_degree_map
        del cardinalities
        del unmarked
        del unmarked_basis
def compute_cohomology(value=None):
    id_to_degree_map = {}  # key = id, value = filtration appearence/degree.
    cardinalities = {}
    unmarked = {}  # key = card value = list [] of unmarked simplices of that cardinality
    unmarked_basis = {}  # key = id, value = set of ids

    try:
        while True:
            if value is None:
                value = (yield (-1, -1, -1))

            birth = death = value.degree  # since, we ignore such cases typically.
            dim = value.k
            # Though theoretically its not the right thing to do.
            try:
                if value.k < 0:  # meaning i want to just go throw indices for infinity intervals
                    flag = False
                    for card in unmarked.keys():
                        for id_sigma in unmarked.get(card, []):
                            birth = id_to_degree_map[id_sigma]
                            death = INF
                            flag = True
                            value = (yield (birth, death, card - 1))
                            unmarked[card].remove(id_sigma)

                    if flag is False:
                        yield (-1, -1, -1)

                elif value.k == 0:  # Vertices
                    cardinalities[value.id] = value.k + 1
                    id_to_degree_map[value.id] = value.degree

                    list_of_unmarked = unmarked.get(value.k + 1, [])
                    if list_of_unmarked:
                        unmarked[value.k + 1].append(value.id)
                    else:
                        unmarked[value.k + 1] = [value.id]

                    unmarked_basis[value.id] = set([value.id])
                    value = (yield (birth, death, dim))

                else:  # 1-simplex, 2-simplex, etc.
                    destroyer_flag = False
                    most_recently_killed_degree = -1
                    most_recently_killed_id = -1
                    list_bases_toupdate = []  # list of id whose bases needs update
                    boundary_obj = Boundary()
                    # list_of_unmarked = []

                    boundary_set = set([])
                    card_boundary = value.k
                    for sign, boundary in boundary_obj.compute_boundary(value):
                        # constuct string repr of the simplex
                        boundary_str = '|'.join([str(b) for b in boundary.kvertices])
                        id_boundary = getId(boundary_str)
                        boundary_set = boundary_set.union([id_boundary])

                    # for each simplex of cardinality card_boundary, check whether
                    # the corresponding boundary set intersection is empty or have cardinality even
                    for id_sigma in unmarked.get(card_boundary, []):
                        basis_sigma = unmarked_basis.get(id_sigma)
                        intersecting_set = basis_sigma.intersection(boundary_set)
                        len_intersecting_set = len(intersecting_set)
                        if len_intersecting_set % 2:  # odd => destroyer
                            destroyer_flag = True
                            list_bases_toupdate.append(id_sigma)
                            if id_to_degree_map[id_sigma] > most_recently_killed_degree:
                                most_recently_killed_id = id_sigma
                                most_recently_killed_degree = id_to_degree_map[id_sigma]

                    # If it is a destroyer simplex/ -ve simplex.
                    if destroyer_flag:
                        birth = most_recently_killed_degree
                        death = value.degree
                        dim = cardinalities[most_recently_killed_id] - 1

                        unmarked[dim + 1].remove(most_recently_killed_id)

                        # update the bases for all ids in list_bases_toupdate except most_recently_killed_id
                        for id in list_bases_toupdate:
                            if id != most_recently_killed_id:
                                unmarked_basis[id].symmetric_difference_update(unmarked_basis[most_recently_killed_id])

                        del unmarked_basis[most_recently_killed_id]

                        unmarked_basis[value.id] = set([value.id])
                        id_to_degree_map[value.id] = value.degree

                        value = (yield (birth, death, dim))

                    else:  # New cocycle. A +ve simplex/creator.
                        cardinalities[value.id] = value.k + 1

                        list_of_unmarked = unmarked.get(value.k + 1, [])
                        if list_of_unmarked:
                            unmarked[value.k + 1].append(value.id)
                        else:
                            unmarked[value.k + 1] = [value.id]

                        unmarked_basis[value.id] = set([value.id])
                        id_to_degree_map[value.id] = value.degree

                        value = (yield (birth, death, dim))

                        # we must add the basis for value.id irrespective of it being creator or destroyer

            except Exception, e:
                value = e
    finally:
        # print "Don't forget to clean up when 'close()' is called."
        # del indices
        del id_to_degree_map
        del cardinalities
        del unmarked
        del unmarked_basis
    def compute(self):
        """
        Compute the persistent cohomology
        """
        unmarked = {
        }  # key = card value = list [] of unmarked simplices' id of that cardinality
        unmarked_basis = {
        }  # key = id, value = set of ids whose linear combination makes the basis

        for sigma in self.filtration_ar:
            if sigma.k == 0:  # Vertices
                list_of_unmarked = unmarked.get(sigma.k + 1, [])
                if list_of_unmarked:
                    if sigma.id not in unmarked[sigma.k + 1]:
                        unmarked[sigma.k + 1].append(
                            sigma.id)  # avoid repeatedly storing an id
                        unmarked_basis[sigma.id] = {sigma.id}
                else:
                    unmarked[sigma.k + 1] = [sigma.id]
                    unmarked_basis[sigma.id] = {sigma.id}

            else:
                destroyer_flag = False
                most_recently_killed_degree = -1
                most_recently_killed_id = -1
                list_bases_toupdate = []  # list of id whose bases needs update
                boundary_obj = Boundary()
                # list_of_unmarked = []

                boundary_set = set([])
                card_boundary = sigma.k
                for sign, boundary in boundary_obj.compute_boundary(sigma):
                    # constuct string repr of the simplex
                    boundary_str = '|'.join(
                        [str(b) for b in boundary.kvertices])
                    id_boundary = getId(boundary_str)
                    boundary_set = boundary_set.union([id_boundary])

                # for each simplex of cardinality card_boundary, check whether
                # the corresponding boundary set intersection is empty or have even cardinality
                for id_sigma in unmarked.get(card_boundary, []):
                    basis_sigma = unmarked_basis.get(id_sigma)
                    intersecting_set = basis_sigma.intersection(boundary_set)
                    len_intersecting_set = len(intersecting_set)
                    if len_intersecting_set % 2:  # odd => destroyer
                        destroyer_flag = True
                        list_bases_toupdate.append(id_sigma)
                        deg_id_sigma = self.filtration_ar[
                            self.simplexid_to_indexmap[id_sigma]].degree
                        if deg_id_sigma > most_recently_killed_degree:
                            most_recently_killed_id = id_sigma
                            most_recently_killed_degree = deg_id_sigma
                        # else:
                        #     # When both id_sigma and most_recently_killed_id have same degree, we resolve the ordering
                        #     # by their index in the filtration_ar
                        #     if self.simplexid_to_indexmap[id_sigma] > self.simplexid_to_indexmap[
                        #         most_recently_killed_id] and deg_id_sigma == most_recently_killed_degree:
                        #         most_recently_killed_id = id_sigma
                        #         most_recently_killed_degree = deg_id_sigma

                # If it is a destroyer simplex/ -ve simplex.
                if destroyer_flag:
                    birth = most_recently_killed_degree
                    death = sigma.degree
                    simplex_index = self.simplexid_to_indexmap[
                        most_recently_killed_id]
                    simplex_to_destroy = self.filtration_ar[simplex_index]
                    assert isinstance(simplex_to_destroy, KSimplex)
                    dim = simplex_to_destroy.k
                    self.intervals[dim].append((birth, death))

                    # mark this id. we only keep unmarked ids, unmarked == pivot
                    unmarked[dim + 1].remove(most_recently_killed_id)

                    # update the bases for all ids in list_bases_toupdate except most_recently_killed_id
                    for id in list_bases_toupdate:
                        if id != most_recently_killed_id:
                            unmarked_basis[id].symmetric_difference_update(
                                unmarked_basis[most_recently_killed_id])

                    del unmarked_basis[most_recently_killed_id]

                    unmarked_basis[sigma.id] = {sigma.id}

                else:  # New cocycle. A +ve simplex/creator.
                    list_of_unmarked = unmarked.get(sigma.k + 1, [])
                    if list_of_unmarked:
                        if sigma.id not in unmarked[sigma.k + 1]:
                            unmarked[sigma.k + 1].append(sigma.id)
                            unmarked_basis[sigma.id] = {sigma.id}
                    else:
                        unmarked[sigma.k + 1] = [sigma.id]
                        unmarked_basis[sigma.id] = {sigma.id}

        for card in unmarked.keys():
            for id_sigma in unmarked.get(card, []):
                birth = self.filtration_ar[
                    self.simplexid_to_indexmap[id_sigma]].degree
                death = INF
                self.intervals[card - 1].append((birth, death))
示例#10
0
def test_boundary_op():
    delta = Boundary()
    delta.compute_boundary(KSimplex([1, 2, 3]))
    print delta