From 9776b4863bbcb886e2e181d6d90a3242e8cdd66f Mon Sep 17 00:00:00 2001
From: Lionel GUEZ <guez@lmd.ens.fr>
Date: Fri, 10 Mar 2023 16:45:57 +0100
Subject: [PATCH] Polish

---
 .../Documentation_texfol/documentation.tex    | 28 +++++++++++++------
 Trajectories/Tests/segments_networkx.py       |  3 +-
 Trajectories/cost_function.py                 |  3 +-
 Trajectories/segments.py                      | 17 +++++++++--
 Trajectories/trajectories.py                  | 11 ++++++--
 5 files changed, 46 insertions(+), 16 deletions(-)

diff --git a/Trajectories/Documentation_texfol/documentation.tex b/Trajectories/Documentation_texfol/documentation.tex
index d27ccf88..859f4fb0 100644
--- a/Trajectories/Documentation_texfol/documentation.tex
+++ b/Trajectories/Documentation_texfol/documentation.tex
@@ -68,15 +68,6 @@ instantanés ?
 
 Les trajectoires forment une partition du graphe en géodésiques.
 
-\verb+segments.py+. La mémoire vive nécessaire augmente à peu près
-linéairement avec la taille du graphe lu. La taille du graphe global
-sur 28 ans, pour une orientation donnée est de \np{3e7} arêtes. Le
-temps d'exécution augmente à peu près linéairement avec le nombre de
-noeuds du graphe lu (différent du nombre d'arêtes). Sur Ciclad, comme
-d'habitude, les variations de temps sont grandes d'une exécution à
-l'autre, d'un noeud d'exécution à
-l'autre. Cf. \href{../experiences.ods}{expériences}.
-
 \verb+cost_function.py+. En extrayant les $10^6$ premières arêtes dans
 le graphe des tourbillons instantanés, les tourbillons sont étalés sur
 un an environ. Le graphe des segments contient environ \np{8e4}
@@ -119,4 +110,23 @@ Mémoire vive nécessaire pour charger le graphe global sur 28 ans, sans
 attributs, avec Graph-tool : environ \np{6.1} GiB. Il faut au moins 11
 GiB avec Networkx.
 
+\section{\texttt{segments.py}}
+
+La mémoire vive nécessaire augmente à peu près
+linéairement avec la taille du graphe lu. La taille du graphe global
+sur 28 ans, pour une orientation donnée est de \np{3e7} arêtes. Le
+temps d'exécution augmente à peu près linéairement avec le nombre de
+noeuds du graphe lu (différent du nombre d'arêtes). Sur Ciclad, comme
+d'habitude, les variations de temps sont grandes d'une exécution à
+l'autre, d'un noeud d'exécution à
+l'autre. Cf. \href{../experiences.ods}{expériences}.
+
+Dans la boucle sur v qui lisse le graphe, le degré de v3 n'est pas
+modifié. Le degré sortant de v2 peut être diminué (à 0) si et
+seulement si v n'a pas de successeur.
+
+Pour qu'un noeud soit isolé avant son tour dans la boucle, il faut que
+dans le graphe initial son degré entrant soit nul. Il faut donc un
+segment isolé.
+
 \end{document}
diff --git a/Trajectories/Tests/segments_networkx.py b/Trajectories/Tests/segments_networkx.py
index ad2ca66b..ddf4cb07 100755
--- a/Trajectories/Tests/segments_networkx.py
+++ b/Trajectories/Tests/segments_networkx.py
@@ -5,7 +5,6 @@ from networkx.drawing import nx_agraph
 import sys
 
 g = nx.read_edgelist(sys.argv[1], create_using = nx.DiGraph, nodetype = int)
-verts_to_del = [] # list of nodes to remove
 
 for v in g: g.nodes[v]["inst_eddies"] = [v]
 # "inst_eddies" is the list of instantaneous eddies represented by a
@@ -13,6 +12,8 @@ for v in g: g.nodes[v]["inst_eddies"] = [v]
 # script, each node will be a segment and "inst_eddies" will contain
 # the list of eddies in the segment.
         
+verts_to_del = [] # list of nodes to remove
+
 for v in g:
     if g.in_degree[v] == 1:
         v2 = next(g.predecessors(v))
diff --git a/Trajectories/cost_function.py b/Trajectories/cost_function.py
index a8d1dbbc..b7517db6 100755
--- a/Trajectories/cost_function.py
+++ b/Trajectories/cost_function.py
@@ -13,7 +13,8 @@ Input:
 - the SHPC
 
 Output: the graph of segments with cost functions,
-segments_cost_functions.gt or segments_cost_functions.graphml.
+segments_cost_functions.gt or segments_cost_functions.graphml. The
+inst_eddies property of vertices is not modified by this script.
 
 """
 
diff --git a/Trajectories/segments.py b/Trajectories/segments.py
index dc83ff63..10191b0d 100755
--- a/Trajectories/segments.py
+++ b/Trajectories/segments.py
@@ -5,7 +5,9 @@ the graph of segments. A vertex of the new graph is a segment. Input
 file should be an edgelist in CSV format. The new graph is output in
 the binary format of Graph-tool (file with suffix ".gt") or in GraphML
 format (suffix ".graphml".) The algorithm in this script does not rely
-on any ordering of the input edgelist.
+on any ordering of the input edgelist. By construction, in the output
+graph of segments, the list of instantaneous eddies associated to each
+segment is in ascending order.
 
 """
 
@@ -37,12 +39,21 @@ t0 = t1
 # Processing:
 
 g.vp['inst_eddies'] = g.new_vp('vector<int>')
-print('Collapsing into segments...')
 for v in g.vertices(): g.vp.inst_eddies[v] = [int(g.vp.name[v])]
+# "inst_eddies" is the list of instantaneous eddies represented by a
+# node. At first, each node represents only itself. At the end of the
+# script, each node will be a segment and "inst_eddies" will contain
+# the list of eddies in the segment.
+
+print('Collapsing into segments...')
 g.set_fast_edge_removal()
-verts_to_del = []
+verts_to_del = [] # list of nodes to remove
 
 for v in g.vertices():
+    # Loop invariant: (for any vertex v', inst_eddies[v'] is in
+    # ascending order) and (for any couple of vertices (v', v''), if
+    # v' is a predecessor of v'' then inst_eddies[v'][-1] <
+    # inst_eddies[v''][0])
     if v.in_degree() == 1:
         v2 = next(v.in_edges()).source()
         
diff --git a/Trajectories/trajectories.py b/Trajectories/trajectories.py
index e33c15ce..0f09d3fc 100755
--- a/Trajectories/trajectories.py
+++ b/Trajectories/trajectories.py
@@ -16,15 +16,22 @@ import numpy as np
 
 if len(sys.argv) != 2: sys.exit("Required argument: input-graph")
 g = graph_tool.load_graph(sys.argv[1])
+
 traj_prop = g.new_vertex_property('int', val = - 1)
+# Trajectory index to which a segment belongs. - 1 means the segment
+# does not belong yet to any trajectory. The trajectory index is also
+# the index in lists traj_segm and expanded_traj.
+
 all_cost_functions = g.get_edges([g.edge_properties.cost_function])
 
 # Array of indices that sort on cost function:
 ind_cf = np.argsort(all_cost_functions[:, 2])
 
 ind_traj = - 1 # initialize index of trajectory
-traj_segm = [] # trajectories as lists of segments
-expanded_traj = [] # trajectories as lists of instantaneous eddies
+traj_segm = [] # an element of traj_segm is a trajectory, represented
+               # by a lists of segments
+expanded_traj = [] # an element of expanded_traj is a trajectory,
+                   # represented by a list of instantaneous eddies
 
 # Loop over edges in ascending order of cost function:
 for i in ind_cf:
-- 
GitLab