Introduction
For a long time I thought about choosing a mathematical object that is interesting not only from the point of view of discrete mathematics, but also functional analysis, and try to program it.
This object became the so-called
topological spaces . Naturally, the finite volume of the representation of objects in the computer’s memory does not allow to model the topological spaces in mathematics with absolute precision, and therefore it remains to be content with finite topologies.
Fortunately, this is one of those objects for which a finiteness not only allows one to operate with standard mathematical concepts, but also simplifies some of them. Moreover, it is quite interesting to explore objects for which we
have no way to measure the distance between points. Yes, yes, you heard right. We have no such possibility in the general topology.
')
But first things first.
Definition
First we give the classical definition of a topological space.
Let X be an arbitrary set. A system τ of its subsets is called a topology if the following conditions are satisfied:
- The empty set and the set X belong to the topology.
- The union of an arbitrary number of sets that belong to a topology belongs to a topology.
- The intersection of a finite number of sets belonging to a topology belongs to topology.
An arbitrary number of sets in this case means that we can also take associations of a countable or even an uncountable number of sets. Naturally, this makes sense only in the case of infinite sets.
As I said, everything in the computer is finite. How our definition of topology will change if we assume that X is a finite set.
It is easy to see that the definition will sound like this:
Let X be an arbitrary set of finite cardinality. A system τ of its subsets is called a finite topology if the following conditions are satisfied:
- The empty set and the set X belong to the topology.
- If two sets belong to topology, then their union belongs to topology
- If two sets belong to topology, then their intersection belongs to topology
For convenience, we will omit the word “final”. Note that topology is a set of sets. Unfortunately, the standard classes for the set, represented in the Java language, did not suit me, mainly because the join and intersection operations in the Set interface change the set object, but I need to. that the object is changed only when elements are added to it.
Therefore, I created the following class to represent sets based on a linked list.
Class FSet <T>package generaltopology; public class FSet<T> { protected class Node { T elem; Node next; public Node(T a) { elem = a; next = null; } } Node first; public FSet() { first = null; } public boolean contains(T a) { boolean flag= false; Node x = first; while (x != null && !flag) { if (x.elem.equals(a)) flag = true; x = x.next; } return flag; } public boolean subset(FSet<T> b) { boolean flag = true; Node x = first; while (x != null && flag) { if (!b.contains(x.elem)) flag = false; x = x.next; } return flag; } public void add(T a) { Node x = new Node(a); if (!contains(a)) { x.next = first; first = x; } } public FSet<T> union(FSet<T> b) { FSet<T> c = new FSet<>(); for (Node a = first; a != null; a = a.next) c.add(a.elem); for (Node a = b.first; a != null; a = a.next) c.add(a.elem); return c; } public FSet<T> intersection(FSet<T> b) { FSet<T> c = new FSet<>(); for (Node a = first; a != null; a = a.next) if (b.contains(a.elem)) c.add(a.elem); return c; } public FSet<T> complement(FSet<T> b) { FSet<T> c = new FSet<>(); for (Node a = first; a != null; a = a.next) if (!b.contains(a.elem)) c.add(a.elem); return c; } @Override public boolean equals(Object b) { FSet<T> bb = (FSet<T>)b; return subset(bb) && bb.subset(this); } @Override public String toString() { String s = "["; for (Node a = first; a != null; a = a.next) if (a.next != null) s += a.elem + ","; else s += a.elem; s += ']'; return s; } }
This class is the main brick for building the final topology. We now turn to the topology itself. So far, I have only spoken about it, but have not said what a topological space is. This is a pair (X, τ) of a set and its topology.
Therefore, the advancement of the class looks like this (I want the set to consist of integers, but thanks to the use of generic classes, you can easily correct the code for an arbitrary type).
public class Topology extends FSet<FSet<Integer>> { static final FSet<Integer> EmptySet = new FSet<>(); FSet<Integer> X; }
Now the question is how the topology constructor should look. Note that topology is always a system of subsets of the set X.
So, here is the first independent task for you, dear reader. Prove the following statement:
Let X be an arbitrary set. Then the system τ consisting of the empty set and the set X forms a topology.It was easy, right? This topology is called trivial. So let's always create a trivial topology at the beginning of use, adding the necessary sets later using the add method of the superclass.
public Topology(FSet<Integer> X) { add(X); add(EmptySet); this.X = X; }
But that is not all. We added some element to the topology. Does it remain a topology from the addition of an element or not? Testing for the implementation of the second and third properties is easy to write, but the question is where to write it. We cannot call it when adding an element, because then we will not be able to get a good topology due to the output of the error “Ah, this is not a topology”. So, at the creation stage, it is necessary to “forgive” this error for a while, and only then make it a good kick: we will add a check box and a verification method
private boolean _isTopology; public boolean isTopology() { boolean flag = true; Node x = first; while (x != null && flag) { Node y = x.next; while (y != null && flag) { FSet<Integer> a = x.elem; FSet<Integer> b = y.elem; FSet<Integer> u = a.union(b); FSet<Integer> i = a.intersection(b); if (!contains(u)) flag = false; if (!contains(i)) flag = false; y = y.next; } x = x.next; } _isTopology = flag; return flag;
But it was just a warm-up. Now we give a few more definitions.
The sets in the topology τ are called open.Sets that are complementary to open are called closed.Most students are confused. Here is the following task:
Let X = {1,2,3,4}, and τ = {∅, {1}, {2,4}, {1,2,4}, {1,2,3,4}}. Determine if the following sets are open or closed?
A = {1}
B = {1,3}
C = {1,2,3,4}
D = {2,3}
Naturally, the verification of these two properties is carried out by the following methods:
public boolean isOpen(FSet<Integer> a) { if (!_isTopology) throw new IllegalArgumentException(" "); if (!a.subset(X)) throw new IllegalArgumentException(" "); return contains(a); } public boolean isClosed(FSet<Integer> a) { if (!_isTopology) throw new IllegalArgumentException(" "); if (!a.subset(X)) throw new IllegalArgumentException(" "); return contains(X.complement(a)); }
Exceptions are thrown if the system does not form a topology, or the transmitted set is not a subset of X of the topological space.
If you slipped through the past task without trying to solve it, then you will be surprised why the second method is not called through the first one. And if you decide, you will understand.
The answer to the previous problemA is an open set. It is included in the topology.
B is a closed set. It is the complement of the set {2,4} included in the topology.
C - open and closed set. It is open, because it is included in the topology. But it is also closed, since it is the complement of the empty set that is included in the topology.
D - neither an open nor a closed set , since neither it nor its complement are included in the topology.
Next, you need to introduce the concept of neighborhood.
The neighborhood of the point x is any open set containing xThe neighborhood of the set M is any open set G containing MProblem 3. Let a topological space from the previous problem be given. Find all neighborhoods of points of the set X, as well as neighborhoods of the set {1,2}Note that there can be several neighborhoods of both a point and a set. Here I have already found a class that satisfies me: ArrayList. Accordingly, I simply display a list of found neighborhoods.
public ArrayList<FSet<Integer>> getNeighbourhoods(Integer x) { if (!_isTopology) throw new IllegalArgumentException(" "); ArrayList<FSet<Integer>> neighbourhoods = new ArrayList<>(); Node a = first; while (a != null) { FSet<Integer> open = a.elem; if (open.contains(x)) neighbourhoods.add(open); a = a.next; } return neighbourhoods; } public ArrayList<FSet<Integer>> getNeighbourhoods(FSet<Integer> M) { if (!_isTopology) throw new IllegalArgumentException(" "); if (!M.subset(X)) throw new IllegalArgumentException(" "); ArrayList<FSet<Integer>> neighbourhoods = new ArrayList<>(); Node a = first; while (a != null) { FSet<Integer> open = a.elem; if (M.subset(open)) neighbourhoods.add(open); a = a.next; } return neighbourhoods; }
Answer to task 3- Neighborhood point 1: {1}, {1,2,4}, {1,2,3,4}
- Neighborhood point 2: {2,4}, {1,2,4}, {1,2,3,4}
- Neighborhoods point 3: {1,2,3,4}
- Neighborhood point 4: {2,4}. {1,2,4}, {1,2,3,4}
- Neighborhood of the set {1,2}: {1,2,4}, {1,2,3,4}
In a topological space where such familiar terms as distance, metric or norm are absent, the neighborhood is the basic foundation for constructing geometry in such spaces.
So some more definitions.
A point x from the set X is called a touch point of the set M lying in X if each neighborhood of the point x contains at least one point from MA point x from a set X is called a limit point of a set M lying in X if every neighborhood of x contains at least one point from M different from XSo, as always, as long as the knowledge is fresh, I offer you simple tasks after the definition, followed by code, and then a solution.
Problem 4. In the previous topological space, find the points of contact and limit points of the set M = {2,3} .
Note that the definition does not require belonging to a set of topology.
The code for the corresponding points:
boolean isAdherencePoint(Integer x, FSet<Integer> M) { if (!_isTopology) throw new IllegalArgumentException(" "); if (!M.subset(X)) throw new IllegalArgumentException(" "); boolean flag = true; if (M.equals(EmptySet)) return false; ArrayList<FSet<Integer>> neighbourhoods = getNeighbourhoods(x); int i = 0; while (i < neighbourhoods.size() && flag) { FSet<Integer> a = neighbourhoods.get(i); FSet<Integer>.Node t = M.first; boolean containsM = false; while (t != null && !containsM) { if (a.contains(t.elem)) containsM = true; t = t.next; } if (!containsM) flag = false; i++; } return flag; } boolean isLimitPoint(Integer x, FSet<Integer> M) { if (!_isTopology) throw new IllegalArgumentException(" "); if (!M.subset(X)) throw new IllegalArgumentException(" "); boolean flag = true; if (M.equals(EmptySet)) return false; ArrayList<FSet<Integer>> neighbourhoods = getNeighbourhoods(x); int i = 0; while (i < neighbourhoods.size() && flag) { FSet<Integer> a = neighbourhoods.get(i); FSet<Integer>.Node t = M.first; boolean containsM = false; while (t != null && !containsM) { if (!t.elem.equals(x) && a.contains(t.elem)) containsM = true; t = t.next; } if (!containsM) flag = false; i++; } return flag; }
AnswerTouch Points: 2,3,4
Limit points: 3
Now we have everything to define an important concept in mathematics: the closure of a set.
The closure of the set M is the set of all its points of contact. It is usually denoted as [M].
FSet<Integer> getClosure(FSet<Integer> M) { if (!_isTopology) throw new IllegalArgumentException(" "); if (!M.subset(X)) throw new IllegalArgumentException(" "); FSet<Integer> c = new FSet<>(); FSet<Integer>.Node a = X.first; while (a != null) { if (isAdherencePoint(a.elem,M)) c.add(a.elem); a = a.next; } return c; }
Again, continuing to work with our topological space, we can see that [{2,3}] = {2,3,4}, while we got a closed set.
Another important concept is the concept of an
isolated point.A point x is called an isolated point of the set M, if there exists a neighborhood of it that does not contain other points from M.Problem 5. Prove that x = 2 is an isolated point of the set M = {2,3} boolean isIsolated(Integer x, FSet<Integer> M) { if (!_isTopology) throw new IllegalArgumentException(" "); if (!M.subset(X)) throw new IllegalArgumentException(" "); boolean flag = false; ArrayList<FSet<Integer>> neighbourhoods = getNeighbourhoods(x); int i = 0; while (i < neighbourhoods.size() && !flag) { FSet<Integer> a = neighbourhoods.get(i); FSet<Integer>.Node t = M.first; boolean containsothers = false; while (t != null && !containsothers) { if (!t.elem.equals(x) && a.contains(t.elem)) containsothers = true; t = t.next; } if (!containsothers) flag =true; i++; } return flag; }
Further, it is necessary to understand that on the same set it is possible to introduce different topologies, thereby obtaining different spaces. But between the topologies, you can establish a partial order.
It is said that the topology of p1 is weaker than the topology of p2, if p1 is entirely contained in p2, and stronger otherwise.
Obviously, the weakest topology is the trivial topology.
Problem 6. Let an arbitrary set X be given. Introduce the strongest topology on it. List all open and closed sets. @Override public int compareTo(Topology o) { int a; if (!_isTopology || !o._isTopology) throw new IllegalArgumentException(" "); if (subset(o)) a = -1; else if (equals(o)) a = 0; else if (o.subset(this)) a = 1; else throw new IllegalArgumentException(" "); return a; }
AnswerThe strongest topology that can be introduced on the set X is the so-called discrete topology consisting of all the subsets of the set X. In it all the subsets of the set X are both open and closed at the same time.
And the last concept I want to talk about in this article is a trace of topology.
The trace of the topology t on the set A, lying in X, is the topology t A , consisting of all sets of the form B ∩ A, where B belongs to the topology.Problem 7. Prove that the trace of the topology of m on the set A forms a topology on the set A Topology getTrace(FSet<Integer> A) { if (!_isTopology) throw new IllegalArgumentException(" "); if (!A.subset(X)) throw new IllegalArgumentException(" "); FSet<Integer> AX = A.intersection(X); Topology c = new Topology(AX); Node f = first; while (f != null) { c.add(f.elem.intersection(A)); f = f.next; } return c; }
Conclusion
This is the end of the first part of my series of articles on topological spaces and the programming of their subclass: finite topologies in the Java language. In the next part, I plan to talk a little about the base topology, however, in the case of finite topologies, this concept is quite simplified, since finite topological spaces by default have a countable base, and we will see what happens next. It is likely that we will talk about continuous mappings of one topological space to another. It would be nice to try to program such an object, right?
Thanks for attention!