7

I want to develop a simple way to define topologies on finite sets $X=\{1,2,\dots,n\}$ for computational experiments.

Does any function $c:X\to \mathcal P(X)$, such that $x\in c(x)$, define a closure operator on $X$?

The idea is that $c$ should define a closure operator by $$\mathrm{cl}(\{x_1,\cdots,x_m\})=\overline{\{x_1,\cdots,x_m\}}=\bigcup_{k=1}^{m} c(x_k)$$

Lehs
  • 13,791
  • 4
  • 25
  • 77

6 Answers6

7

You need an additional property to guarantee that the closure operator will be idempotent. Requiring $$x \in c(y) \Rightarrow c(x) \subseteq c(y)$$ in addition to $x \in c(x)$ is necessary and sufficient.

6

It's sufficient to define a relation $x \le y$, the specialisation order, (so just a subset of $X^2$), which is a pre-order, so $x \le x$ for all $x$,and $x \le y$ and $y \le z$ implies $x \le z$. ($\le$ is reflexive and transitive).

This relation is defined in a topological space by $x \le y$ iff $x \in \overline{\{y\}}$. But if we start with a preorder $\le$, we can define a topology: $\overline{\{y\}}$ is then defined by $\downarrow y = \{x \in X: x \le y\}$ and $\overline{A} = \cup_{x \in A}\downarrow x$.

The set of finite topological spaces is just the set of finite pre-orders.

Henno Brandsma
  • 242,131
  • Is there a nice way to check transitivity computationally? – Lehs Jun 11 '17 at 09:26
  • 1
    Define a matrix $A$ by $a_{i,j} = 1$ iff $i \le j$ (labeling the points $1$ to $n$). Compute $B$ as $A^2$ over the integers, and replace all entries $>0$ by $1$. If $B= A$ we have a transitive relation, I think. – Henno Brandsma Jun 11 '17 at 09:32
  • See https://math.stackexchange.com/q/228898/4280 Brian has the same idea as I did. – Henno Brandsma Jun 11 '17 at 09:34
  • Thank you! I will try that. – Lehs Jun 11 '17 at 09:34
  • It's even an equivalence of categories: continuous functions correspond to order-preserving maps and vice-versa. So your investigation in finite top spaces can just as well be done with such finite sets equipped with a pre-order and studying the order-preserving maps. – rwols Jun 11 '17 at 14:50
  • @rwols: I intend to study a certain definition of continuity and its generalisation from functions to relations: https://math.stackexchange.com/questions/907899/a-proof-that-continuity-of-fx-to-y-is-equivalent-to-overlinef-1m-sub – Lehs Jun 11 '17 at 17:01
2

No. First of all, it must be a function $c\colon\mathcal{P}(X)\longrightarrow\mathcal{P}(X)$. Besides, it must satisfy these conditions:

  1. $A\in\mathcal{P}(X)\Longrightarrow A\subset c(A)$;
  2. $A,B\in\mathcal{P}(X)\wedge A\subset B\Longrightarrow c(A)\subset c(B)$;
  3. $A\in\mathcal{P}(X)\Longrightarrow c\bigl(c(A)\bigr)=c(A)$.
2

If you want a simple way to define finite topological spaces, the simplest ones are nothing more that a chain of inclusions:

$\emptyset \subset A_1 \subset A_2 \dots \subset A_n ( = X) $

The ${A_i}^{'}s$ are your closed sets.

This doesn't describe all topologies on $X$ , but it may be useful for your experiments.

CopyPasteIt
  • 11,366
  • Thanks! It could be useful. Do you have any idea of the limitations? – Lehs Jun 11 '17 at 13:25
  • The chain is a sub-lattice of the power set of X. "More generally any finite topological space has a lattice of sets as its family of open {or closed} sets." See https://en.wikipedia.org/wiki/Birkhoff%27s_representation_theorem – CopyPasteIt Jun 11 '17 at 13:58
  • 1
    Notice how you would define your function $c$ with this chain. The closure of any $x$ is the first $A_i$ in which $x$ is a member. – CopyPasteIt Jun 11 '17 at 14:12
2

The easiest way to define topologies is to read them from a list. Complete lists of inequivalent (non-homeomorphic) topological spaces on $n$ points for $2\leq n\leq7$ and $T_0$ topological spaces on 8 and 9 points can be found here:

https://www.mathtransit.com/finite_topological_spaces.php

The C program below can be used to get more spaces. It calculates the transitive closure of a reflexive relation using Warshall's algorithm. A good introduction to this subject can be found here:

https://www.jstor.org/stable/2689890

#include    <stdio.h>
#include    <stdlib.h>

unsigned long    closure(unsigned long *cl, unsigned long set);
unsigned long    complement(unsigned long set);
unsigned long    interior(unsigned long *cl, unsigned long set);

unsigned long    maxbits = (unsigned long) (8*sizeof(unsigned long));   // sizeof() returns byte count
unsigned long   *twopower;                                              // twopower[i] = 2^i
int              spacesize;                                             // cardinality of topological space

int main(int argc, const char **argv)
{
    twopower = (unsigned long *)malloc(maxbits * sizeof(unsigned long));
    if (twopower == 0)
    {
        printf("\nCould not allocate space for twopower array.\n");
        exit(0);
    }

    twopower[0] = 1;
    for (int k=1; k<maxbits; k++) twopower[k] = 2*twopower[k-1];

    spacesize = 10;
    if (spacesize > maxbits)
    {
        printf("\nSpace cardinality cannot exceed maxbits.\n");
        exit(0);
    }

    int **adjacency_matrix, row, col;

    adjacency_matrix = (int **)malloc(spacesize * sizeof(int *));
    if (adjacency_matrix==0)
    {
        printf("Could not allocate space for adjacency matrix.");
        exit(0);
    }

    for (row=0; row<spacesize; row++)
    {
        adjacency_matrix[row] = (int *)malloc(spacesize * sizeof(int));
        if (adjacency_matrix[row]==0)
        {
            printf("Could not allocate space for row %d.", row);
            exit(0);
        }
    }

    /*
     *  Randomly generate adjacency matrix of reflexive relation R:
     */

    int discretion = 8; // higher discretion => more 0's

    for (row=0; row<spacesize; row++)
        for (col=0; col<spacesize; col++)
        {
            if (col == row) adjacency_matrix[row][col] = 1; // this makes R reflexive
            else adjacency_matrix[row][col] = !(rand() % discretion);
        }

    /*
     *  Use Warshall's algorithm to get transitive closure of R (preserves reflexivity):
     */

    int mid;

    for (mid=0; mid<spacesize; mid++)
        for (row=0; row<spacesize; row++)
            for (col=0; col<spacesize; col++)
                adjacency_matrix[row][col] = adjacency_matrix[row][col] || (adjacency_matrix[row][mid] && adjacency_matrix[mid][col]);

    /*
     *  We now have the adjacency matrix of a preorder, i.e., topological space.
     *
     *  Assuming space = {0,...,spacesize-1} and subsets are represented by bit strings of length spacesize,
     *  we define closure of singleton {x} as
     *
     *  cl[x] = binary integer obtained by reversing row x (where rows are numbered 0,...,spacesize-1) of adjacency matrix.
     *
     *  Reversing the bits gives us the nice property that point x belongs to set S iff S & 2^x = 2^x.
     *
     *  Next we calculate cl[x] for x = 0,...,spacesize-1:
     */

    unsigned long *cl;

    cl = (unsigned long *)malloc(spacesize * sizeof(unsigned long));
    if (cl==0)
    {
        printf("Could not allocate space for closures of singletons.");
        exit(0);
    }

    for (row=0; row<spacesize; row++)
    {
        cl[row] = 0;
        for (col=0; col<spacesize; col++)
            cl[row] = cl[row] + adjacency_matrix[row][col] * twopower[col];
    }

    /*
     *  [do experiments here]
     */

    free(cl);
    for (row=0; row<spacesize; row++) free(adjacency_matrix[row]);
    free(adjacency_matrix);
    free(twopower);

    return EXIT_SUCCESS;
}

unsigned long closure(unsigned long *cl, unsigned long set)
{
    int i;
    unsigned long closure = 0;

    for (i=0; i<spacesize; i++)
        if (set & twopower[i]) closure = closure | cl[i];
    return closure;
}

unsigned long complement(unsigned long set)
{
    unsigned long complement, space = twopower[spacesize]-1;

    complement = ~set & space;
    return complement;
}

unsigned long interior(unsigned long *cl, unsigned long set)
{
    unsigned long interior;

    interior = closure(cl, set);
    interior = complement(interior);
    interior = closure(cl, interior);
    return interior;
}
mathematrucker
  • 1,513
  • 10
  • 21
0

Starting with an arbitrary function $c:X\to\mathcal P(X)$ such that $\forall x\in X:x\in c(x)$, this should be an algorithm to transform $c$ to a function that defines a closure operator, due to the accepted answer:

$0:\quad$ $\mathrm{ready}\leftarrow\mathrm{true}$
$1:\quad$ $i\leftarrow 1$
$2:\quad$ $j\leftarrow 1$
$3:\quad$ if $i\in c(j)$ and $c(i)\cap c(j)\neq c(i)$ then $c(j)\leftarrow c(j)\cup c(i)$ ; $\mathrm{ready}\leftarrow\mathrm{false}$
$4:\quad$ $j\leftarrow j+1$
$5:\quad$ if $j\leq n$ then goto $3$
$6:\quad$ $i\leftarrow i+1$
$7:\quad$ if $i\leq n$ then goto $2$
$8:\quad$ if not ready then goto $0$

Lehs
  • 13,791
  • 4
  • 25
  • 77