przemys‚aw witek

23
Przemyslaw Witek Uniwersytet Jagielloński Homology computation by reduction of chain complexes Praca semestralna nr 1 (semestr letni 2011/12) Opiekun pracy: Marian Mrozek

Upload: others

Post on 03-Feb-2022

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Przemys‚aw Witek

Przemysław Witek

Uniwersytet Jagielloński

Homology computation by reduction of chain complexes

Praca semestralna nr 1

(semestr letni 2011/12)

Opiekun pracy: Marian Mrozek

Page 2: Przemys‚aw Witek

1 Cubical sets and their homology

Cubical sets are data structures of high importance in computational homology because of theirsimplicity. Moreover, for many applications (such as image processing) this is the most naturalrepresentation one can think of. In this section we present the basic concepts related to cubical setsfrom topological and algebraical point of view.

1.1 Topology

1.1.1 Elementary cubes

An elementary interval is a closed interval I ⊆ R such that I = [l, l] or l = [l, l + 1] for l ∈ Z.Elementary intervals of length 0 are said to be degenerate (we write [l] instead of [l, l] in this case)while those of length 1 - nondegenerate.

An elementary cube Q is a finite product of elementary intervals:

Q = I1 × I2 × · · · × Id ⊆ Rd

I1, I2, . . . , Id are called the components of Q. We will sometimes refer to them using Ii(Q) notation.

The set of all elementary cubes is defined by:

K :=∞⋃

d=1

Kd

where Kd denotes the set of all elementary cubes in Rd.

Some of the subsets of an elementary cube are especially important. Let Q,P ∈ K. Then:

• Q is a face of P (Q � P ) if Q ⊆ P ,

• Q is a proper face of P (Q ≺ P ) if Q � P and Q 6= P ,

• Q is a primary face of P if Q ≺ P and dim Q = dim P − 1.

For elementary cube Q ∈ Kd we define its embedding number (emb Q) to be d whereas Q’s dimension(dim Q) is the number of its nondegenerate components. Obviously, 0 ≤ dim Q ≤ emb Q.We also introduce the following notation:

Kk := {Q ∈ K | dim Q = k}

andKd

k := Kk ∩ Kd

1.1.2 Cubical sets

A set X ⊆ Rd is cubical if it can be written as a finite union of elementary cubes.

For X - cubical set, we define:K(X) = {Q ∈ K | Q ⊆ X}

1

Page 3: Przemys‚aw Witek

andKk(X) = {Q ∈ K(X) | dim Q = k}

Let Q,P ∈ K(X). Then:

• Q is a maximal face in X if it is not a proper face of some P ∈ K(X),

• Kmax(X) is the set of maximal faces in X,

• Q is a free face in X if it is a proper face of exactly one elementary cube in X.

If Q is free in X and Q ≺ P (P is unique because Q is free) then P ∈ Kmax(X) and dim Q = dim P−1

1.1.3 Example

Figure 1 shows a cubical set X. Some of its properties are listed so that the reader may get familiarwith new notions.

Figure 1: An example of a cubical set consisting of 3 cubes

• [−1, 1], [−3], [0, 2], [−1, 0], [2, 3], [0] are elementary intervals: [0] and [-3] are degenerate whileothers are nondegenerate

• Q1, Q2, Q3 are elementary cubes as products of elementary intervals: Q1 = [−1, 1]× [−1, 1]×[−1, 1]Q2 = [0, 2]× [−1, 0]× [−3]Q3 = [2, 3]× [0]× [−3][0, 2], [−1, 0], [−3] are the components of Q2

• X is a cubical set as a finite sum of elementary cubes:X = Q1 ∪Q2 ∪Q3

2

Page 4: Przemys‚aw Witek

• emb Q1 = emb Q2 = emb Q3 = 3 as all the elementary cubes are embedded in R3

• Q2 is a 2-dimensional object so dim Q2 = 2. Similarily, dim Q1 = 3, dim Q3 = 1

• K2(Q1) is a set of Q1’s primary (and also free) faces:K2(Q1) = {[−1]× [−1, 1]× [−1, 1], [1]× [−1, 1]× [−1, 1], [−1, 1]× [−1]× [−1, 1], [−1, 1]× [1]×[−1, 1], [−1, 1]× [−1, 1]× [−1], [−1, 1]× [−1, 1]× [1]}

• Elementary cubes from K1(Q1) are Q1’s proper faces. These are not primary though.

• The only maximal face in Q1 is Q1 itself.

1.2 Algebra

An elementary k-chain Q is an algebraic object that we associate with an elementary cube Q. Wealso introduce notation for the set of all elementary k-chains of Rd:

Kdk := {Q | Q ∈ Kd

k}and the set of all elementary chains of Rd:

Kd :=∞⋃

k=0

Kdk

We now want to be able to take finite sums of elementary k-chains. For this purpose we have to saywhat exactly an elementary k-chain is. For Q ∈ Kd

k we define Q : Kdk → Z by:

Q(P ) :=

{1 if P = Q

0 otherwise

and we call Q the elementary chain dual to the elementary cube Q. Now, every sum of the form:

c = α1Q1 + α2Q2 + · · ·+ αmQm

will be called a k-chain. Thus, each k-chain is also a function from Kdk to Z. A set of all k-chains is

denoted by Cdk . Cd

k is the free abelian group and Kdk is its basis.

Definition Let c1 =∑m

i=1 αiQi and c2 =∑m

i=1 βiQi be chains from Cdk . The scalar product of c1

and c2 is defined as:

〈c1, c2〉 :=m∑

i=1

αiβi

Given a cubical set X ⊆ Rd, the set of k-chains of X is denoted by Ck(X) = {Q | Q ⊆ X}. It is asubgroup of Cd

k .The cubical boundary operator ∂k : Cd

k → Cdk−1 is a homomorphism of groups. Therefore, it is

sufficient to define it only for group generators (elementary k-chains). For d = 1 it is defined by:

∂kQ :=

{0 if Q = [l]

[l + 1]− [l] if Q = [l, l + 1]

For higher dimensions it can be defined inductively.Groups of cubical k-chains (Ck(X)) and cubical boundary operators restricted to chains from X forma cubical chain complex :

C(X) := {Ck(X), ∂Xk }k∈Z

3

Page 5: Przemys‚aw Witek

1.3 Homology

We will now define homology of a cubical chain complex.

Let X ⊆ Rd be a cubical set. Ck(X) denotes the set of X’s k-chains. We would like to distin-guish two special classes of k-chains: cycles and boundaries.Cycles are elements of Zk(X) = ker∂X

k . From the definition of kernel we have:

z ∈ Zk(X)⇔ ∂z = 0

Boundaries are elements of Bk(X) = im∂Xk+1. From the definition of image we have:

z ∈ Bk(X)⇔ ∃c∈Ck+1(X)∂c = z

Every boundary is a cycle, so Bk(X) is a subgroup of Zk(X). Of course, both Bk(X) and Zk(X) aresubgroups of Ck(X).

We say that cycles z1, z2 ∈ Zk(X) are homologous if z1−z2 ∈ Bk(X). Homologousity is an equivalencerelation and elements of the quotient group Zk(X)/Bk(X) are equivalence classes. We introduce thisrelation to discard cycles that are boundaries as they are not interesting for us.

The kth homology group of X is the quotient group

Hk(X) := Zk(X)/Bk(X)

and the homology of X is a collection of homology groups:

H∗(X) := {Hk(X)}k∈Z

Example We would like to discover the homology of a point in Rd. Let x = [l1] × [l2] × · · · × [ld]be an elementary cube representing this point. C0(X) ∼= Z, Z0(X) = C0(X) ∼= Z and B0(X) = 0.Therefore, H0(X) ∼= Z/0 ∼= Z. kth homology groups for k ≥ 1 are all trivial since Ck(X) = 0 ifk ≥ 1.

1.4 Elementary collapse

Elementary collapse is a procedure that allows us to reduce the size of a cubical set making homologycomputation easier. The idea is based on the fact mentioned in the introduction: small changes inthe space do not affect its topological properties (here - its homology).

Definition Let X be a cubical set, Q its free face and P - the unique cube in K(X) such that Q isa proper face of P . Let K′(X) := K(X) \ {Q,P} and X ′ :=

⋃R∈K′(X)R. Then X ′ is a cubical set

obtained from X via an elementary collapse of P by Q.

The most important property of an elementary collapse is that it does not change the homology ofthe set. We have the following:

Theorem 1.1. Let X be a cubical set and X ′ is obtained from X via an elementary collapse ofP ∈ Kk(X) by Q ∈ Kk−1(X). Then

H∗(X ′) ∼= H∗(X)

4

Page 6: Przemys‚aw Witek

The proof is given in [2, p. 70].

By induction, we are also able to perform a sequence of elementary collapses without changinghomology. Finally we get a complex that is (hopefully) significantly smaller and its homology can beeasily computed.

Example X = [0, 1]× [0, 1] ⊂ R2. We will perform a sequence of elementary collapses:

(1)-(2) collapse [0, 1]× [0, 1] by [0]× [0, 1]

(2)-(3) collapse [0, 1]× [1] by [0, 1]× [0, 1]

(3)-(4) collapse [1]× [0, 1] by [1, 1]× [1, 1]

(4)-(5) collapse [0, 1]× [0] by [1, 0]× [1, 0]

(1) (2) (3) (4) (5)

Figure 2: An elementary collapse of a square.

Subsequent cubical sets are shown in the Figure 2. We have reduced 2D square consisting of 9 cubesto a single point.

1.5 Elementary reduction

Elementary reduction is a generalization of elementary collapse from the previous subsection. Whileelementary collapse did not touch any of the generators (despite of the ones being reduced) anelementary reduction will modify the boundary map. Therefore, the complex we get as an outputmay not be cubical but we accept that fact as it enables us to perform reductions that would beimpossible otherwise.

Definition (Reduction pair) Let C = {Ck, ∂k}k∈Z be an abstract chain complex. A reduction pair(reducible pair) is a pair of generators (a, b) such that a ∈ Cm−1, b ∈ Cm and 〈∂b, a〉 = ±1.

A reduction pair defines a collection of homomorphisms π:

πk :=

c− 〈c,a〉〈∂b,a〉∂b if k = m− 1

c− 〈∂c,a〉〈∂b,a〉b if k = m

c otherwise

where c ∈ Ck. In fact, π is a chain map (see [2, p. 155]).

Let C = {Ck, ∂k}k∈Z. We will use π to reduce C. We want to express the reduction in the termof generators. Assume Wk is a fixed basis for Ck for each k. Let (a, b) be a reduction pair for

5

Page 7: Przemys‚aw Witek

a ∈ Wm−1, b ∈ Wm,m ∈ Z. πk is an identity for k /∈ {m− 1,m} so it is sufficient to examine how itacts on generators from Wm−1 and Wm:

π(ai) = ai −〈ai, a〉〈∂b, a〉∂b = ai − 0 = ai

π(a) = a− 〈a, a〉〈∂b, a〉∂b = a− 1〈∂b, a〉(∂b− 〈∂b, a〉 a+ 〈∂b, a〉 a) = −∂b− 〈∂b, a〉 a〈∂b, a〉

π(bi) = bi −〈∂bi, a〉〈∂b, a〉 b

π(b) = b− 〈∂b, a〉〈∂b, a〉b = b− b = 0

where ai ∈Wm−1, bi ∈Wm.

Example (from [2, p. 156])

a2 a3

a

a4a5

a1

b1

b2

b3

b4

b5

b6

b

(a) Before reduction

a2 a3

a4a5

a1

b1

b2

b′3

b′4

b5

b6

(b) After reduction

Figure 3: Elementary reduction of cubical set X using pair (a, b). After reduction X is not cubicalanymore.

Let X be a cubical set from Figure 3a.The bases are:

W0 := {a1, a2, a3, a4, a5, a}W1 := {b1, b2, b3, b4, b5, b6, b}

The boundary operator on base elements is:

∂b1 = a1 − a2

∂b2 = a3 − a2

∂b3 = a− a3

∂b4 = a4 − a∂b5 = a4 − a5

∂b6 = a5 − a1

6

Page 8: Przemys‚aw Witek

∂b = a− a1

We choose (a, b) as a reduction pair. Then:

πai = ai

πa = −∂b− 〈∂b, a〉 a〈∂b, a〉 = −a− a1 − 1a1

= a1

πbi = bi −〈∂bi, a〉〈∂b, a〉 b = bi for i ∈ {1, 2, 5, 6}

πb3 = b3 −〈∂b3, a〉〈∂b, a〉 b = b3 −

11b = b3 − b

πb4 = b4 −〈∂b4, a〉〈∂b, a〉 b = b4 −

−11b = b4 + b

πb = 0

Just like an elementary collapse, elementary reduction does not change the homology of the complex:

Theorem 1.2. Let C = {Ck, ∂k}k∈Z and C′ = {C ′k, ∂′k}k∈Z be chain complexes such that C′ = π(C).Then

H∗(C′) ∼= H∗(C)

The proof is given in [2, p. 159].

Elementary reduction is the main building block in CCR algorithm implementation provided insection 2.

2 CCR algorithm and its implementation

Due to the fact that in real-world applications cubical sets can consist of millions of cubes, the basicalgorithm described in the previous section is not effective enough. There is a need to reduce thesize of a complex as outlined in section 1.4.

2.1 CCR Algorithm

At first, we have to express algebraic notions in the terms of a programming language (C++):

typedef vector<set<Generator>> Generators ;typedef vector<matrix<Generator , int>> BoundaryMap ;typedef pair<Generator , Generator> Reduc ib lePair ;

For a reader familiar with C++ and STL, it is obvious what pair, vector and set types represent.The only new type is matrix, which has the following interface:

template <typename IndexType , typename ScalarType>class matrix {

typedef map<IndexType , ScalarType> Row;typedef map<IndexType , ScalarType> Column ;

ScalarType get ( IndexType r , IndexType c ) ;

7

Page 9: Przemys‚aw Witek

Row row ( IndexType r ) ;Column c o l ( IndexType c ) ;

}Generators’ boundaries are stored as columns in the appropriate matrices. Coboundaries may beassociated with matrices’ rows.

Below is the most general version of an algorithm performing one-step reduction:

void reducePair ( Generators generator s , BoundaryMap bd ,int q ,Generator a , Generator b) {

FOREACH( c , bd [ q ] . row ( a ) )bd [ q ] . c o l ( c ) −= bd [ q ] . get ( a , b)∗bd [ q ] . get ( a , c )∗bd [ q ] . c o l (b ) ;

g ene ra to r s [ q ] . e r a s e (b ) ;g ene ra to r s [ q−1] . e r a s e ( a ) ;bd [ q +1] . de l e t e row (b ) ;bd [ q ] . d e l e t e c o l (b ) ;bd [ q ] . d e l e t e row ( a ) ;bd [ q−1] . d e l e t e c o l ( a ) ;

}Having one-step reduction implemented, we move on to chain complex reduction (CCR) algorithm:

void reduce ( Generators generator s , BoundaryMap bd) {int top dim = gene ra to r s . s i z e ( ) − 1 ;for ( int q = top dim ; q >= 1 ; q−−) {

Generator a , b ;while ( f i ndReduc ib l ePa i r ( generator s , bd , q , &a , &b ) )

reducePair ( generator s , bd , q , a , b )}

}

2.2 Correctness

One-step reduction algorithm always stops as it only performs finite number of well-defined matrixoperations such as deleting a row or subtracting one column from another.For its correctness it is essential that a chain complex represented as (generators, bd) has the samehomology before and after reduction. But this is exactly the consequence from Theorem 3.2.CCR algorithm contains while loop so we have to show that at some point there is no reducible pairto use and the loop terminates. But it comes from the fact that each one-step reduction decreasesthe number of generators so we eventually quit the loop because there are no more generators left.CCR algorithm correctness can be proven by induction on the number of reduction steps i.e. sincechain complex’s homology does not change after one-step reduction, it does not change after a finitenumber of such reductions as well.

2.3 Implementation

CCR algorithm is implemented in C++. The choice was influenced by the need to integrate CCRwith capd library. Lets talk a bit about C++ features that are extensively used in the whole capd

8

Page 10: Przemys‚aw Witek

and in CCR implementation. Class templates are among the most important of them.

Templates allow us to express general ideas and then concretize them efficiently. Consider thissimple example from STL (Standard Template Library):

template <class T>class vec to r {

T∗ e lements ;. . .

}The code does not change whether we want the vector to store integers, strings or some user-definedobjects. Templates implement static polymorphism as opposed to dynamic polymorphism achievedthrough virtual methods. Templates have one big advantage over virtual methods. They do notimpose any overhead connected with storing v-tables and calling methods indirectly through thosetables. Instead, templates are more like substitutions (each occurrence of T is substituted with intif we want to have a vector of integers).

One another language-specific feature used in my code are preprocessor macros (actually, these comefrom C language). Macros are a powerful tool but should be used with caution. I only use 3 macrosfor iteration because they make the code more concise:

#define FOR( i , a , b ) for ( int i = ( a ) ; i <= (b ) ; ++i )#define FORD( i , a , b ) for ( int i = ( a ) ; i >= (b ) ; −− i )#define FOREACH( i t , c o l l )

for (BOOST TYPEOF( ( c o l l ) . begin ( ) ) i t = ( c o l l ) . begin ( ) ;i t != ( c o l l ) . end ( ) ;

++i t )

Going back to CCR algorithm, while it may look simple at the first glance, there is a number ofproblems that have to be solved to obtain an efficient implementation.

2.3.1 SparseMatrix class

The first question is: How do we store matrices in memory and perform row (column) operations?Storing them as 2-dimensional arrays would be wasteful as there are few nonzero entries (matriceswe are dealing with are sparse in their nature). On the other hand, array provides quick randomaccess to its entries and this is something we need. SparseMatrix class used in my implementationaims at achieving the maximum efficiency in the context of CCR algorithm:

template <typename IndexType , typename ScalarType>class SparseMatrix {

typedef map<IndexType , ScalarType> Row;typedef map<IndexType , ScalarType> Column ;. . .map<IndexType , Row> rows ;map<IndexType , Column> c o l s ;

}As we can see, there is a possibility to refer to an entry either by row or by column. It is extremelyimportant to keep these two structures synchronized. Therefore, we do give access to these structures

9

Page 11: Przemys‚aw Witek

only through public methods.

To get a single entry from the matrix, we call the following method:

ScalarType get ( const IndexType& r , const IndexType& c ) const {ColumnsIterator c o l s i t = c o l s . f i n d ( c ) ;i f ( c o l s i t == c o l s . end ( ) )

return ScalarType ( 0 ) ;const Column& c o l = c o l s i t −>second ;ColumnIterator c o l i t = c o l . f i n d ( r ) ;return ( c o l i t == c o l . end ( ) ) ? ScalarType (0 ) : c o l i t −>second ;

}If we find the entry in matrix, we return it. Otherwise, we return 0.

The method below assigns an entry a new value (or creates a new entry if non-existing):

void s e t ( const IndexType& r , const IndexType& c ,const ScalarType& value ) {

i f ( va lue == ScalarType ( 0 ) ) {rows [ r ] . e r a s e ( c ) ;c o l s [ c ] . e r a s e ( r ) ;

} else {rows [ r ] [ c ] = value ;c o l s [ c ] [ r ] = value ;

}}We don’t store zeros to be memory-efficient.

To delete a row r, we have to remove an entry corresponding to r from all columns and afterthat remove the row itself:

void de l e t e row ( const IndexType& r ) {FOREACH( row it , rows [ r ] ) {

const IndexType& c = row it−> f i r s t ;c o l s [ c ] . e r a s e ( r ) ;

}rows . e r a s e ( r ) ;

}Deleting a column is performed similarily.

We are now ready to provide a full implementation of one-step reduction using just defined op-erations:

void reducePair (int q , const GeneratorCode& a , const GeneratorCode& b) {

FOREACH( c , bd [ q ] . row ( a ) ) i f ( c != b) {ScalarType c o e f f = bd [ q ] . get ( a , b) ∗ bd [ q ] . get ( a , c ) ;FOREACH( r , bd [ q ] . c o l (b ) ) i f ( r != a ) {

ScalarType value = bd [ q ] . get ( r , c ) − c o e f f ∗ bd [ q ] . get ( r , b ) ;

10

Page 12: Przemys‚aw Witek

bd [ q ] . s e t ( r , c , va lue ) ;}

}bd [ q +1] . de l e t e row (b ) ;bd [ q ] . d e l e t e c o l (b ) ;bd [ q ] . d e l e t e row ( a ) ;bd [ q−1] . d e l e t e c o l ( a ) ;

}For each generator c in a’s coboundary we perform column subtraction. The checks (c != b) and (r!= a) are to prevent from modifying the map we are iterating over.

Various implementations of map interface and their impact on the overall program performanceare discussed in 2.3.2.

2.3.2 Map implementations

Map (or associative array) is ”a collection of unique keys and a collection of values, where each keyis associated with one value” [7]. Usually, we expect map to implement the following operations:

• insert a new key-value pair into the map if the key is not present

• erase a value for a given key

• find a value corresponding to a given key

• iterate over all elements in a collection

hhhhhhhhhhhhhhhhhImplementationOperation

insert erase find iterate

Binary search tree n n n nRed-black tree log n log n log n n

Direct-addressed map 1 1 1 number of distinct keysHash map with chaining 1 1 1 size of hash table

Table 1: Various data structures as map implementations.

SparseMatrix class uses maps in two ways: for storing rows (columns, respectively) and entries inthe single row (column, respectively). We will call the former an external map and the latter aninternal map. The keys are matrix indices which in the case of CCR are generator codes (generatorsare encoded using consecutive integer numbers). The values are the whole rows in the case of externalmap and scalars in the case of internal one. There are several data structures that can be used asmap implementations, varying in computational complexity. Some of them are presented in the table1 along with operations’ complexities (n denotes the number of elements in data structure). In thecase of the first three data structures, complexities in the worst case are given. For hash map withchaining, complexities are for average case (assuming uniform hashing, see [3]). There are clearlytwo main classes of maps: tree-based, which need a full order on keys (the searches are performedby key comparisons) and hashtable-based, which need a hash function on keys. We will look closerat the latter.

11

Page 13: Przemys‚aw Witek

Direct-addressed map is a perfect solution for an external map as the maximum number of ele-ments stored (generators) is known in advance and keys come from a (relatively) small subset ofinteger numbers (generator codes). One problem we have to overcome is iteration time proportionalto the number of possible keys, not the number of actual elements. To achieve O(n) iteration time,we bind the elements in the singly-linked list. A Node is defined as:

struct Node {KeyValuePair item ;IntType next ;bool i s f i l l e d ;bool i s removed ;

} ;

Apart from the item itself, only one integer (the reference to the next map entry) and two bits arestored in the node so the memory per-element overhead is very low comparing to red-black tree (3pointers, typically).The nodes are stored in the array of a fixed size:

Node∗ map ;map = new Node [ capac i ty ] ;

Generators’ erases are done in a lazy manner. When erase method is called, is removed flag is setto true for an element. The element is being removed from the list during iteration, when we haveaccess to its predecessor.The DirectMap class is the full implementation of direct-addressed map.

Although simple and effective, direct map is unsuitable as an implementation of an internal map. Itis due to the fact that its memory usage after creation is constant (we allocate memory for the initialcontent and don’t release it while generators are being erased). We need some more sophisticateddata structure for this purpose. This is where HashMap class comes.HashMap class uses chaining as a collision resolution method. To ensure O(n) iteration time, allelements are bound in the singly-linked list and each hash table entry points to the head of a sublistcontaining elements having the same hash code. The Node here is defined as:

struct Node {KeyValuePair item ;Node∗ next ;bool i s h e a d ;bool i s removed ;

} ;

Per-element memory overhead is 2 pointers (one in the hash table, one in the node) and 2 bits inthis case.The nodes are stored in the array:

Node∗∗ map ;map = new Node ∗ [PRIMES[ pr ime index ] ] ;

where PRIMES is an array containing prime numbers used as hash table sizes. When using moduloas a hash function it is important to use prime table size to ensure that all entries are likely to beoccupied. Moreover, the primes used should be chosen to be far from the powers of 2 (see the chapterdedicated to hash tables in [3]). The prime index changes with the actual number of elements in the

12

Page 14: Przemys‚aw Witek

hash table. Before inserting an element into the table, we check if size > PRIMES[prime index+1].If so, we increase prime index and rehash all the elements to the new table. Similarily, we do rehashingif size < PRIMES[prime index − 1] before erasing. Rehashing is costly, but it is performed inan amortized constant time so it does not increase computational complexity of insert and eraseoperations.Erases are done in a lazy manner, just like in DirectMap class (the only difference is that here we uselist with pointers, not cursors). is head field is needed in find operation: we stop searching for a keyif either we find a key or we encounter is head = true which indicates that the sublist correspondingto a given hash is over.

2.3.3 Searching for reducible pairs

Another interesting problem regarding data structures is: How do we find reducible pairs? The naiveapproach would be to iterate over all entries in the matrix and pick the first encountered reduciblepair:

bool f indAnyReduciblePair (int q , GeneratorCode& a , GeneratorCode& b) {

FOREACH( c , bd [ q ] . c o l s )FOREACH( r , bd [ q ] . c o l ( c ) )

i f ( i s I n v e r t i b l e (bd [ q ] . get ( r , c ) ) ) {a = r ;b = c ;return true ;

}return fa l se ;

}Then, the whole CCR algorithm would look like this:

void reduceNaive ly ( ) {FORD(q , top dim , 1) {

GeneratorCode a , b ;while ( f indAnyReduciblePair (q , &a , &b ) )

reducePair (q , a , b ) ;}

}There are two problems with this approach. Firstly, it has to traverse a big piece of a matrix untilit finds an invertible element (and a corresponding reducible pair). Secondly, the reduction of aresulting pair can take very long. It is due to the fact that the number of operations performed inreducePair method is proportional to both a’s coboundary size and b’s boundary size. By choosingreducible pair more carefully, it is possible to increase overall algorithm performance. Instead ofpicking the first encountered reducible pair, we can remember the pair with the lowest cost, wherecost is defined as:

cost(q, a, b) = (bd[q].row(a).size()− 1) ∗ (bd[q].col(b).size()− 1)

and it is equal to the number of matrix’s set operations in reducePair routine. The resulting proce-dure, call it findBestReduciblePair, has to traverse the whole matrix every time. If we incorporateit into CCR algorithm, we get so called greedy algorithm. Greedy algorithms always do what seems

13

Page 15: Przemys‚aw Witek

to be the best choice at the moment.

We are now close to a pretty good solution. Rather than searching for a minimum every timewe need a reducible pair, lets sort all reducible pairs by their cost and reduce them in this order:

void reduceViaSort ( ) {FORD(q , top dim , 1) {

while ( true ) {vector<ReduciblePair> p a i r s ;FOREACH( c , bd [ q ] . c o l s )

FOREACH( r , bd [ q ] . c o l ( c ) )i f ( i s I n v e r t i b l e (bd [ q ] . get ( r , c ) )

p a i r s . push back ( Reduc ib lePair ( r , c , c o s t (q , r , c ) ) ) ;i f ( p a i r s . empty ( ) )

break ;s o r t ( p a i r s . begin ( ) , p a i r s . end ( ) ) ;FOREACH( pair , p a i r s )

i f ( i s I n v e r t i b l e (bd [ q ] . get ( pa i r . a , pa i r . b ) ) )reducePair (q , pa i r . a , pa i r . b ) ;

}}

}Observant reader will notice that reduceV iaSort procedure is not equivalent to the greedy approachdescribed above. It comes from the fact that the costs change as we add/remove entries to/from thematrix. This leads us to the next method, reduceWithPriorityQueue. In this method, we insertall reducible pairs into the priority queue (pairs with lower cost have higher priority) and then keepreducing the best pair until no pairs are left. Right before reduction we extract the set of pairsaffected by the reduction (”affected” in this context means that the priority of a reducible pair canchange) and right after reduction we insert all affected pairs back to the queue with recomputedpriorities. We also insert new reducible pairs that emerged during column subtraction.

All the methods described in this subsection are members of ReducibleFreeChainComplex class.

2.4 Complexity

Lets start with the complexity od reducePair method. As mentioned in the previous section, thenumber of set operations in reducePair(q, a, b) call is proportional to:

cost(q, a, b) = (bd[q].row(a).size()− 1) ∗ (bd[q].col(b).size()− 1).

Operation set has O(log n) worst-case complexity when balanced binary search trees (e.g. red-blacktrees) are used and O(1) average-case complexity when hash maps are used as external and internalmap. Using direct map as an external map doesn’t improve the complexity, but the constant hiddenin big O notation is then significantly lower. In the rest of this subsection we will assume thatboth external and internal maps are implemented using HashMap class and the complexities will beaverage-case complexities.The average-case complexity of reducePair(q, a, b) is therefore:

O(#boundary(b) ∗#coboundary(a)) ≤ O(#generators(q) ∗#generators(q − 1)).

14

Page 16: Przemys‚aw Witek

Both findAnyReduciblePair and findBestReduciblePair may have to visit every entry in theboundary map matrix, so their worst-case complexity can be estimated as:

O(#generators(q) ∗#generators(q − 1)).

Lets estimate the complexity of reduceNaively:For a given q, the number of iterations of while loop is not greater than the number of generatorsoccurring in bd[q] which is:

#generators(q) + #generators(q − 1).

Finally, the average-case complexity of reduceNaively can be bounded by:

O(top dim∑

q=1

(#generators(q) + #generators(q − 1)) ∗#generators(q) ∗#generators(q − 1))

≤ O(top dim ∗ (top dimmaxq=0

#generators(q))3).

If we assume that the top dimension of a chain complex is constant (which is often the case, as it iscommon to analyze 2D or 3D sets), we obtain

O((top dimmaxq=0

#generators(q))3)

time complexity in average case (compare with the analysis of a different variant of CCR algorithmgiven in [1, p. 14]).reduceWithPriorityQueue has no advantage over reduceNaively in the terms of complexity. It iseven worse because it has to keep priorities up-to-date which adds logarithmic factor (when std::mapis used as priority queue) to the overall complexity. The same holds for reduceV iaSort. However,the next subsection shows that these heuristics are useful in real-world examples.

2.5 Experimental results

Various implementations of the CCR algorithm were tested for correctness and performance:

• reduceNaively, reducible pairs found using findAnyReduciblePair

• reduceNaively, reducible pairs found using findBestReduciblePair

• reduceV iaSort

• reduceWithPriorityQueue

Moreover, various data structures were used to implement external and internal maps in SparseMatrixclass:

• both external and internal maps implemented using std::map (red-black tree)

• both external and internal maps implemented using HashMap

• external map implemented using DirectMap, internal map implemented using std::map

• external map implemented using DirectMap, internal map implemented using HashMap

15

Page 17: Przemys‚aw Witek

Input file Number of generators Number of pairs reducedTxS1.fcub 73728 36860

random3d6.bmd 99796 49765pplanexs1.fcub 183600 91797

randomD5s7f5c1.bmd 309943 152605S1xkleinbot.fcub 402144 201068

RFCubSet d4s16f50.cub 1039731 517059TxT.fcub 2359296 1179640

RFCubSet d4s20f50.cub 2483687 1234027S1p4.fcub 5308416 2654200

pplanexT.cub 5875200 2937594

Table 2: Input files with cubical sets used for testing.

The test set consisted of several input files (see Table 2) containing cubical sets with known homologies(computed using an earlier implementation of the same algorithm).Each implementation was giving the same resulting homologies (correctness was not a problem).Moreover, the number of reduced pairs was the same in every case. There were, however, noticabledifferences in running times.

The first experiment’s goal was to determine which data structures work best in SparseMatrixclass implementation. reduceV iaSort algorithm was used in each case to ensure that the order of re-ductions is always the same. It is important as different orders yield different reduction costs makingthe comparison much harder.Results are presented in the table 3. Rows correspond to input files used in testing. There arefour major columns corresponding to four data structures variants described above (in the formatExternalMap/InternalMap). Each of these columns is divided in two parts: creation of Reducible-FreeChainComplex and its reduction (excluding searching for a pair to reduce). There are twonumbers in each cell: processor time and world time (both given in seconds) spent on computation.As we can see, DirectMap/HashMap combination turned out to be the fastest regardless of input size.Big differences between world time and processor time in the biggest test are a result of memory-diskswapping (happening due to high memory usage). This effect is mitigated with DirectMap/HashMap,as they are more memory-efficient than other variants.

The second experiment aimed at comparing different reduction algorithms.Results are presented in the tables: 4, 5 and 6. For each input file, the best result is highlighted ineach column.There is no table for reduceNaively with findBestReduciblePair as it performed very poorly evenfor small input files (as stated in section 2.3.3, to find a reducible pair it has to traverse the wholematrix).reduceNaively with findAnyReduciblePair was not capable of processing inputs quickly when it wasusing DirectMap/HashMap data structures. It is because with findAnyReduciblePair, the order ofreductions depends heavily on how each data structure stores its elements internally. This variantperformed much better with std::map/std::map SparseMatrix implementation since std::map is anordered map (not like HashMap with pretty random order of elements).Most promising solutions are reduceViaSort and reduceWithPriorityQueue. Reduction costs (andconsequently, the time spent in reducePair method) were lower for the latter which is not surprising

16

Page 18: Przemys‚aw Witek

as it always picks the best possible reducible pair. However, it was not sufficient to outperformreduceViaSort. The simplicity and low memory requirements of reduceV iaSort made it a winner inmost cases despite relatively high reduction costs.

2.6 Summary

This work dealt with effective methods of computing homology using elementary reductions. Severalvariants of CCR algorithm were implemented, analyzed and tested. In addition, appropriate datastructures were chosen to implement SparseMatrix class.

The ideal implementation for CCR algorithm would keep a priority queue of reducible pairs andupdate it with little cost. Unfortunately, known priority queues’ implementations have O(log n)time complexity for insert (update, erase) operation and reduction of each pair triggers many suchoperations. Moreover, priority queues consume memory causing a lot of swapping which degradesoverall algorithm performance. Apparently, there is still some place for improvements in priorityqueue implementation.

CCR algorithm implementation is available as ReducibleFreeChainComplex class and it can be usedtogether with other reduction algorithms from capd library.

17

Page 19: Przemys‚aw Witek

Inpu

tfil

eR

educ

tion

cost

map

/map

Has

h/H

ash

Dir

ect/

map

Dir

ect/

Has

hcr

eate

redu

cecr

eate

redu

cecr

eate

redu

cecr

eate

redu

ce

TxS

1.fc

ub26

294

0.50

0.36

0.45

0.29

0.42

0.16

0.42

0.15

0.50

0.40

0.46

0.33

0.42

0.19

0.42

0.19

rand

om3d

6.bm

d42

2494

0.71

0.94

0.65

0.69

0.60

0.52

0.59

0.43

0.71

0.99

0.65

0.74

0.60

0.56

0.59

0.47

ppla

nexs

1.fc

ub28

028

1.47

1.00

1.36

0.84

1.23

0.44

1.21

0.42

1.50

1.09

1.36

0.93

1.23

0.52

1.21

0.50

rand

omD

5s7f

5c1.

bmd

1006

8618

1.92

13.3

11.

878.

581.

639.

601.

626.

581.

9213

.47

1.87

8.72

1.63

9.74

1.62

6.72

S1xk

lein

bot.

fcub

8263

83.

292.

253.

051.

832.

740.

962.

680.

933.

292.

453.

052.

012.

741.

142.

681.

10

RF

Cub

Set

d4s1

6f50

.cub

3594

5095

6.66

61.9

16.

6537

.80

5.56

42.4

05.

4228

.58

6.66

62.4

66.

6538

.29

5.56

42.8

85.

4229

.06

TxT

.fcub

1267

555

22.7

117

.03

20.8

813

.93

18.5

47.

1018

.09

6.76

22.7

118

.26

20.8

815

.01

18.5

48.

1518

.09

7.81

RF

Cub

Set

d4s2

0f50

.cub

2592

9011

616

.79

594.

0016

.62

280.

2313

.84

400.

6513

.68

222.

6016

.79

594.

0116

.62

281.

4313

.85

401.

8513

.69

223.

80

S1p4

.fcub

1135

141

112.

9014

0.90

79.1

818

4.82

95.8

210

2.98

60.5

158

.55

421.

5070

8.42

194.

6852

5.29

331.

7465

4.57

126.

4023

7.14

ppla

nexT

.cub

1288

357

116.

4816

3.45

81.2

192

.36

100.

1112

1.53

60.9

771

.07

389.

4182

7.77

187.

0734

6.77

374.

1176

0.71

118.

4532

8.03

Tab

le3:

Per

form

ance

offo

urva

rian

tsof

Spar

seM

atri

xcl

ass

diffe

ring

inm

apim

plem

enta

tion

sus

ed.

18

Page 20: Przemys‚aw Witek

Inpu

tfil

eR

educ

tion

cost

crea

tere

duce

Pai

rre

duce

Via

Sort

tota

l

TxS

1.fc

ub26

294

0.40

0.15

0.22

0.69

0.40

0.18

0.22

0.70

rand

om3d

6.bm

d42

2494

0.58

0.42

0.54

1.31

0.58

0.47

0.54

1.31

ppla

nexs

1.fc

ub28

028

1.19

0.41

0.60

2.02

1.19

0.49

0.60

2.02

rand

omD

5s7f

5c1.

bmd

1006

8618

1.58

6.67

7.23

9.56

1.58

6.81

7.23

9.56

S1xk

lein

bot.

fcub

8263

82.

650.

931.

374.

512.

651.

111.

374.

51

RF

Cub

Set

d4s1

6f50

.cub

3594

5095

5.34

29.0

231

.16

39.5

15.

3429

.50

31.1

639

.82

TxT

.fcub

1267

555

17.8

16.

809.

6330

.88

17.8

17.

869.

6331

.21

RF

Cub

Set

d4s2

0f50

.cub

2592

9011

613

.41

225.

8323

5.14

263.

8713

.41

227.

0323

5.15

263.

89

S1p4

.fcub

1135

141

68.5

861

.10

73.1

915

2.61

162.

6129

1.96

325.

1750

2.68

ppla

nexT

.cub

1288

357

59.6

864

.48

76.9

714

8.37

120.

0030

2.80

342.

2247

8.72

Tab

le4:

Per

form

ance

ofre

duce

Via

Sort

wit

hD

irec

tMap

/Has

hMap

Spar

seM

atri

xim

plem

enta

tion

.

19

Page 21: Przemys‚aw Witek

Inpu

tfil

eR

educ

tion

cost

crea

tere

duce

Pai

rre

duce

Wit

hPri

orit

yQue

ueto

tal

TxS

1.fc

ub0.

400.

101.

311.

7957

830.

400.

141.

311.

83

rand

om3d

6.bm

d0.

580.

171.

412.

1435

240

0.58

0.22

1.41

2.18

ppla

nexs

1.fc

ub1.

180.

272.

593.

9949

201.

180.

362.

594.

03

rand

omD

5s7f

5c1.

bmd

1.58

0.82

6.45

8.46

4220

261.

580.

986.

458.

48

S1xk

lein

bot.

fcub

2.64

0.62

5.97

9.08

1376

22.

640.

825.

979.

11

RF

Cub

Set

d4s1

6f50

.cub

5.37

2.53

19.9

926

.54

8981

095.

373.

0619

.99

26.8

7

TxT

.fcub

17.6

84.

3748

.18

68.8

216

9816

17.6

85.

6048

.18

69.1

6

RF

Cub

Set

d4s2

0f50

.cub

13.4

413

.06

116.

4613

3.03

5449

349

13.4

414

.38

116.

4613

3.03

S1p4

.fcub

65.5

343

.50

214.

7828

9.82

2885

514

7.62

190.

9737

9.30

539.

01

ppla

nexT

.cub

60.3

448

.88

211.

0328

2.11

1433

0211

6.78

230.

7843

2.17

564.

89

Tab

le5:

Per

form

ance

ofre

duce

Wit

hPri

orit

yQue

uew

ith

Dir

ectM

ap/H

ashM

apSp

arse

Mat

rix

impl

emen

tati

on.

20

Page 22: Przemys‚aw Witek

Inpu

tfil

eR

educ

tion

cost

crea

tere

duce

Pai

rre

duce

Nai

vely

tota

l

TxS

1.fc

ub95

856

0.48

0.39

0.43

0.92

0.48

0.43

0.43

0.92

rand

om3d

6.bm

d32

7727

0.70

0.77

0.85

1.59

0.70

0.82

0.85

1.59

ppla

nexs

1.fc

ub91

057

1.44

0.98

1.10

2.56

1.44

1.07

1.10

2.56

rand

omD

5s7f

5c1.

bmd

2969

9805

1.89

30.2

631

.38

33.4

01.

8930

.43

31.3

833

.43

S1xk

lein

bot.

fcub

3480

103.

282.

332.

605.

933.

282.

542.

605.

93

RF

Cub

Set

d4s1

6f50

.cub

3923

5285

6.60

46.6

450

.02

56.7

66.

6047

.21

50.0

257

.09

TxT

.fcub

2098

4784

22.4

041

.31

43.0

465

.68

22.4

042

.55

43.0

465

.69

RF

Cub

Set

d4s2

0f50

.cub

5902

2189

316

.51

838.

7788

8.21

905.

1516

.51

840.

3288

8.22

905.

17

S1p4

.fcub

9211

6011

0.36

121.

5212

7.50

238.

5235

1.43

585.

8658

8.15

940.

72

ppla

nexT

.cub

2091

7538

110.

7816

7.70

175.

1328

6.58

361.

0864

5.17

648.

4910

11.6

7

Tab

le6:

Per

form

ance

ofre

duce

Nai

vely

wit

hst

d::m

ap/s

td::m

apSp

arse

Mat

rix

impl

emen

tati

onan

dfin

dAny

Red

ucib

leP

air

met

hod

for

findi

ngpa

irs.

21

Page 23: Przemys‚aw Witek

References

[1] T. Kaczynski, M. Mrozek and M. Slusarek, Homology computation by reduction of chain com-plexes, Computers and Math. Appl. (1998).

[2] M. Mrozek, T. Kaczynski and K. Mischaikow, Computational Homology, Springer (2010).

[3] T.H. Cormen, Ch.E. Leiserson, R.L. Rivest and C. Stein, Introduction to algorithms, WNT(2007).

[4] D.S. Dummit and R.S. Foote, Abstract Algebra, Wiley (2003).

[5] http://en.wikipedia.org/wiki/Free abelian group

[6] http://en.wikipedia.org/wiki/Cosine similarity

[7] http://en.wikipedia.org/wiki/Associative array

[8] http://mathwanderer.wordpress.com/2009/07/28/smith-normal-form/

22