source: tol/tol_pkg/GraphTools/GraphTools.tol @ cf0e0df

1941-docker-image-to-testdevel
Last change on this file since cf0e0df was af628fe, checked in by Víctor de Buen <vdebuen@…>, 17 years ago

Cleaning repeated method vertex.in.degree

git-svn-id: ​https://www.tol-project.org/svn/tolp/trunk@1692 be4846ae-f051-483a-831f-b64e7d08527f

  • Property mode set to 100644
File size: 11.8 KB
Line 
1/* -*- mode: C++ -*- */
2//////////////////////////////////////////////////////////////////////////////
3// FILE   : GraphTools.tol
4// PURPOSE: Defines Package GraphTools
5//////////////////////////////////////////////////////////////////////////////
6
7//////////////////////////////////////////////////////////////////////////////
8NameBlock GraphTools =
9//////////////////////////////////////////////////////////////////////////////
10[[
11#Require MatEncode;
12#Require MatQuery;
13
14Text _.autodoc.description = "Functions and classes related with Graph "
15  "theory. In order to get faster behaviour, internal implementation uses "
16  "matrix and sparse matrix to storing and handling with all numerical "
17  "information about vertices and edges and indexed sets to handle with non "
18  "numerical data.";
19Text _.autodoc.url = "";
20Set _.autodoc.keys = [["Graph theory","vertex","edge","adjacent"]];
21Set _.autodoc.authors = [[
22   "vdebuen@tol-project.org",
23   "josp@tol-project.org" ]];
24
25//////////////////////////////////////////////////////////////////////////////
26Class @Graph
27//////////////////////////////////////////////////////////////////////////////
28{
29  Static Text _.autodoc.description = "Class for handling with generic "
30  "indexed by name graphs in TOL. In abstract, a graph is a pair of sets \n"
31  "  V : a finite set of vertices \n"
32  "  E : a finite set of edges relating an input vertex with an output \n"
33  "Each vertex has a set of features related with the system\n"
34  "Each edge also has its own set of features.\n";
35
36  //The identifier of the graph
37  Text _.name;
38  //Indicates if the graph is directed or symmetric
39  Real _.directed;
40  //Features of vertices. First feature must be the identifier of vertices
41  MatEncode::@FeatureSet _.vertex = MatEncode::@FeatureSet::New(?);
42  //Number of vertices
43  Real _.vertex.num = 0; 
44  //Features of edges. First two features must be input and output vertex
45  MatEncode::@FeatureSet _.edge = MatEncode::@FeatureSet::New(?);
46  //Number of edges
47  Real _.edge.num = 0; 
48  //Sparse matrix storing index of edge for each cell (out,in)
49  VMatrix _.edge.map = Rand(0,0,0,0);
50  VMatrix _.edge.adjacency.out = Rand(0,0,0,0);
51  VMatrix _.edge.adjacency.in  = Rand(0,0,0,0);
52  VMatrix _.edge.repeated = Rand(0,0,0,0);
53  Real _.edge.check.repeated = ?;
54  Real _.edge.check.repaired = ?;
55  ////////////////////////////////////////////////////////////////////////////
56  Static Text _.autodoc.member.New = "Creates a new instance of "
57  "Class @Graph";
58  Static @Graph New(Text name, Real directed)
59  ////////////////////////////////////////////////////////////////////////////
60  {
61    @Graph aux =
62    [[
63      Text _.name = name;
64      Real _.directed = directed
65    ]]
66  };
67
68  ////////////////////////////////////////////////////////////////////////////
69  Real initialize(Set vertex.names)
70  ////////////////////////////////////////////////////////////////////////////
71  {
72    Real _.vertex.num := Card(vertex.names);
73    Set For(1,_.vertex.num, Real(Real k)
74    {
75      Text PutName(vertex.names[k], vertex.names[k]);
76      k
77    });
78    Real _.vertex::add.feature.nonnumeric("Identifier", vertex.names);
79    Matrix _.vertex::_.data := DifEq(1/(1-B),Rand(_.vertex.num,1,1,1));
80    Real _.edge::add.feature.numeric("Output");
81    Real _.edge::add.feature.numeric("Input");
82    True
83  };
84
85  ////////////////////////////////////////////////////////////////////////////
86  Text _.autodoc.member.edge.build = "";
87  Real edge.build(Matrix data, Real removeRepeatedEdges)
88  ////////////////////////////////////////////////////////////////////////////
89  {
90    Real _.edge.num := Rows(data);
91    Matrix out_ = SubCol(data,[[1]]);
92    Matrix in_  = SubCol(data,[[2]]);
93    Matrix out  = If(_.directed, out_, Min(in_, out_));
94    Matrix in   = If(_.directed, in_,  Max(in_, out_));
95    Matrix _.edge::_.data := out | in | SubCol(data,Range(3,Columns(data),1));
96    Matrix idx = DifEq(1/(1-B),Rand(_.edge.num,1,1,1));
97    Matrix idx.rep = Rand(_.edge.num,1,1,1);
98    Matrix outInRep = out|in|idx.rep;
99    VMatrix triplet.rep = Triplet(outInRep,_.vertex.num,_.vertex.num);
100    VMatrix _.edge.repeated := Convert(triplet.rep,"Cholmod.R.Sparse");
101    VMatrix _.edge.adjacency.out := Or(_.edge.repeated, Zeros(_.vertex.num));
102    VMatrix _.edge.adjacency.in := Tra(_.edge.adjacency.out);
103    VMatrix _.edge.repeated := _.edge.repeated - _.edge.adjacency.out;
104    Real _.edge.check.repeated := VMatSum(_.edge.repeated);
105    Code funTriplet = Case(
106    !_.edge.check.repeated,
107    {
108      Real _.edge.check.repaired := 0;
109      Triplet
110    },
111    removeRepeatedEdges,
112    {
113      WriteLn("[GraphTools::@Graph "+_.name+"::edge.build()] "+
114              "There was "<<_.edge.check.repeated+
115              " repeated edges that has been removed","W");
116      Real _.edge.check.repaired := _.edge.check.repeated;
117      TripletUnique
118    },
119    1==1,
120    {
121      WriteLn("[GraphTools::@Graph "+_.name+"::edge.build()] "+
122              "There are "<<_.edge.check.repeated+" repeated edges "
123              "but they don't will be deleted","W");
124      Real _.edge.check.repaired := 0;
125      Triplet
126    });
127    VMatrix triplet.map = funTriplet(out|in|idx,_.vertex.num,_.vertex.num);
128    VMatrix _.edge.map := Convert(triplet.map,"Cholmod.R.Sparse");
129    VMatrix _.edge.map.t := Tra(_.edge.map);
130    True
131  };
132
133  ////////////////////////////////////////////////////////////////////////////
134  Text _.autodoc.member.get.vertex.names = "Returns the names of all "
135  "vertices";
136  Set get.vertex.names(Real void)
137  ////////////////////////////////////////////////////////////////////////////
138  {
139    ((_.vertex::_.feature)[1])::_.domain
140  };
141
142  ////////////////////////////////////////////////////////////////////////////
143  Text _.autodoc.member.get.vertex.name = "Returns the name of one "
144  "vertex";
145  Text get.vertex.name(Real idx)
146  ////////////////////////////////////////////////////////////////////////////
147  {
148    (((_.vertex::_.feature)[1])::_.domain)[idx]
149  };
150
151  ////////////////////////////////////////////////////////////////////////////
152  Text _.autodoc.member.get.vertex.index = "Returns the index of a vertex or 0 "
153  "if it not exists";
154  Real get.vertex.index(Text name)
155  ////////////////////////////////////////////////////////////////////////////
156  {
157    FindIndexByName(((_.vertex::_.feature)[1])::_.domain, name )
158  };
159
160  ////////////////////////////////////////////////////////////////////////////
161  Text _.autodoc.member.get.vertex.feature.index = "Returns the index of an "
162  "vertex feature or 0 if it not exists";
163  Real get.vertex.feature.index(Text name)
164  ////////////////////////////////////////////////////////////////////////////
165  {
166    FindIndexByName(_.vertex::_.feature, name )
167  };
168
169  ////////////////////////////////////////////////////////////////////////////
170  Text _.autodoc.member.get.vertex.features = "Returns all the features for "
171  "an vertex";
172  Set get.vertex.features(Real vertex.idx)
173  ////////////////////////////////////////////////////////////////////////////
174  {
175    _.vertex::get.all(vertex.idx)
176  };
177
178  ////////////////////////////////////////////////////////////////////////////
179  Text _.autodoc.member.get.vertex.feature = "Returns specified feature for "
180  "an vertex. Feature identifier can be the name (Text) or the position "
181  "(Real)";
182  Anything get.vertex.feature(
183    Real vertex.idx,
184    Anything feature.id) //Text name or Real num
185  ////////////////////////////////////////////////////////////////////////////
186  {
187    _.edge::get(vertex.idx, feature.id)
188  };
189
190  ////////////////////////////////////////////////////////////////////////////
191  Text _.autodoc.member.get.edge.index = "Returns the index of an edge or 0 "
192  "if it not exists";
193  Real get.edge.index(Real out_, Real in_)
194  ////////////////////////////////////////////////////////////////////////////
195  {
196    Real out  = If(_.directed, out_, Min(in_, out_));
197    Real in   = If(_.directed, in_,  Max(in_, out_));
198    Real edge.idx = VMatDat(_.edge.map, out, in);
199    edge.idx
200  };
201
202  ////////////////////////////////////////////////////////////////////////////
203  Text _.autodoc.member.edge.exists = "Returns true if exists the edge from "
204  "out_ to in_";
205  Real edge.exists(Real out_, Real in_)
206  ////////////////////////////////////////////////////////////////////////////
207  {
208    get.edge.index(out_, in_)!=0
209  };
210
211  ////////////////////////////////////////////////////////////////////////////
212  Text _.autodoc.member.get.edge.feature.index = "Returns the index of an "
213  "edge feature or 0 if it not exists";
214  Real get.edge.feature.index(Text name)
215  ////////////////////////////////////////////////////////////////////////////
216  {
217    FindIndexByName(_.edge::_.feature, name )
218  };
219
220  ////////////////////////////////////////////////////////////////////////////
221  Text _.autodoc.member.get.edge.features = "Returns all the features for "
222  "an edge";
223  Set get.edge.features(Real edge.idx)
224  ////////////////////////////////////////////////////////////////////////////
225  {
226    _.edge::get.all(edge.idx)
227  };
228
229  ////////////////////////////////////////////////////////////////////////////
230  Text _.autodoc.member.get.edge.feature = "Returns specified feature for "
231  "an edge. Feature identifier can be the name (Text) or the position (Real)";
232  Anything get.edge.feature(
233    Real edge.idx,
234    Anything feature.id) //Text name or Real num
235  ////////////////////////////////////////////////////////////////////////////
236  {
237    _.edge::get(edge.idx, feature.id)
238  };
239
240  ////////////////////////////////////////////////////////////////////////////
241  Text _.autodoc.member.vertex.in.degree = "Returns the number of input "
242  "vertices in edges whose output is the specified vertex";
243  ////////////////////////////////////////////////////////////////////////////
244  Real vertex.in.degree(Real vertex.index)
245  {
246    VMatSum(SubCol(_.edge.adjacency.in,[[vertex.index]]))
247  };
248
249  ////////////////////////////////////////////////////////////////////////////
250  Text _.autodoc.member.vertex.out.degree = "Returns the number of output "
251  "vertices in edges whose input is the specified vertex";
252  ////////////////////////////////////////////////////////////////////////////
253  Real vertex.out.degree(Real vertex.index)
254  {
255    VMatSum(SubCol(_.edge.adjacency.out,[[vertex.index]]))
256  }
257
258/*
259PENDIENTE! : Funciones de adyacencia o vecindad de vértices
260
261http://www.absoluteastronomy.com/topics/Adjacency_matrix
262
263////////////////////////////////////////////////////////////////////////////
264Crea las matrices de adyancencia hasta un orden pedido por el usuario y las
265guarda en un set. Sólo crea las que no existan aún. Sólo devuelve la del
266orden solicitado.
267Matrix get.adyacency(Real order)
268////////////////////////////////////////////////////////////////////////////
269
270  ////////////////////////////////////////////////////////////////////////////
271  Text _.autodoc.member.get.adyacent.input = "Returns the set of vertices "
272  "U which are input adyacent with specified order n of a given output "
273  "vertex V \n"
274  "  V -> ... (n-1) ... -> U \n";
275  Set get.input.order(Real V, Real n)
276  ////////////////////////////////////////////////////////////////////////////
277  {
278    VMatrix match = SubCol(_.edge.adjacency.out, [[V]]);
279    Matrix select = VMat2Triplet(Convert(match,"Cholmod.R.Triplet"));
280    If(!Rows(select),Copy(Empty), MatSet(Tra(SubCol(select,[[1]])))[1])   
281  };
282
283  ////////////////////////////////////////////////////////////////////////////
284  Text _.autodoc.member.get.adyacent.output = "Returns the set of vertices "
285  "U which are output adyacent with specified order n of a given input "
286  "vertex V \n"
287  "  U -> ... (n-1) ... -> V \n";
288  Set get.output.order(Real V, Real n)
289  ////////////////////////////////////////////////////////////////////////////
290  {
291    VMatrix match = SubCol(_.edge.adjacency.in, [[V]]);
292    Matrix select = VMat2Triplet(Convert(match,"Cholmod.R.Triplet"));
293    If(!Rows(select),Copy(Empty), MatSet(Tra(SubCol(select,[[1]])))[1])   
294  }
295
296*/
297
298}
299
300]];
Note: See TracBrowser for help on using the repository browser.