1 /* -*- mode: C -*-  */
2 /*
3    IGraph R package.
4    Copyright (C) 2006-2012  Gabor Csardi <csardi.gabor@gmail.com>
5    334 Harvard street, Cambridge, MA 02139 USA
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20    02110-1301 USA
21 
22 */
23 
24 #include "igraph_types.h"
25 #include "igraph_types_internal.h"
26 #include "igraph_memory.h"
27 #include "config.h"
28 
29 #include <math.h>
30 
31 /* internal function */
32 
igraph_2dgrid_which(igraph_2dgrid_t * grid,igraph_real_t xc,igraph_real_t yc,long int * x,long int * y)33 int igraph_2dgrid_which(igraph_2dgrid_t *grid, igraph_real_t xc, igraph_real_t yc,
34                         long int *x, long int *y) {
35 
36     if (xc <= grid->minx) {
37         *x = 0;
38     } else if (xc >= grid->maxx) {
39         *x = grid->stepsx - 1;
40     } else {
41         *x = (long int) floor((xc - (grid->minx)) / (grid->deltax));
42     }
43 
44     if (yc <= grid->miny) {
45         *y = 0;
46     } else if (yc >= grid->maxy) {
47         *y = grid->stepsy - 1;
48     } else {
49         *y = (long int) floor((yc - (grid->miny)) / (grid->deltay));
50     }
51 
52     return 0;
53 }
54 
igraph_2dgrid_init(igraph_2dgrid_t * grid,igraph_matrix_t * coords,igraph_real_t minx,igraph_real_t maxx,igraph_real_t deltax,igraph_real_t miny,igraph_real_t maxy,igraph_real_t deltay)55 int igraph_2dgrid_init(igraph_2dgrid_t *grid, igraph_matrix_t *coords,
56                        igraph_real_t minx, igraph_real_t maxx, igraph_real_t deltax,
57                        igraph_real_t miny, igraph_real_t maxy, igraph_real_t deltay) {
58     long int i;
59 
60     grid->coords = coords;
61     grid->minx = minx;
62     grid->maxx = maxx;
63     grid->deltax = deltax;
64     grid->miny = miny;
65     grid->maxy = maxy;
66     grid->deltay = deltay;
67 
68     grid->stepsx = (long int) ceil((maxx - minx) / deltax);
69     grid->stepsy = (long int) ceil((maxy - miny) / deltay);
70 
71     IGRAPH_CHECK(igraph_matrix_init(&grid->startidx,
72                                     grid->stepsx, grid->stepsy));
73     IGRAPH_FINALLY(igraph_matrix_destroy, &grid->startidx);
74     IGRAPH_VECTOR_INIT_FINALLY(&grid->next, igraph_matrix_nrow(coords));
75     IGRAPH_VECTOR_INIT_FINALLY(&grid->prev, igraph_matrix_nrow(coords));
76 
77     for (i = 0; i < igraph_vector_size(&grid->next); i++) {
78         VECTOR(grid->next)[i] = -1;
79     }
80 
81     grid->massx = 0;
82     grid->massy = 0;
83     grid->vertices = 0;
84 
85     IGRAPH_FINALLY_CLEAN(3);
86     return 0;
87 }
88 
igraph_2dgrid_destroy(igraph_2dgrid_t * grid)89 void igraph_2dgrid_destroy(igraph_2dgrid_t *grid) {
90     igraph_matrix_destroy(&grid->startidx);
91     igraph_vector_destroy(&grid->next);
92     igraph_vector_destroy(&grid->prev);
93 }
94 
igraph_2dgrid_add(igraph_2dgrid_t * grid,long int elem,igraph_real_t xc,igraph_real_t yc)95 void igraph_2dgrid_add(igraph_2dgrid_t *grid, long int elem,
96                        igraph_real_t xc, igraph_real_t yc) {
97     long int x, y;
98     long int first;
99 
100     MATRIX(*grid->coords, elem, 0) = xc;
101     MATRIX(*grid->coords, elem, 1) = yc;
102 
103     /* add to cell */
104     igraph_2dgrid_which(grid, xc, yc, &x, &y);
105     first = (long int) MATRIX(grid->startidx, x, y);
106     VECTOR(grid->prev)[elem] = 0;
107     VECTOR(grid->next)[elem] = first;
108     if (first != 0) {
109         VECTOR(grid->prev)[first - 1] = elem + 1;
110     }
111     MATRIX(grid->startidx, x, y) = elem + 1;
112 
113     grid->massx += xc;
114     grid->massy += yc;
115     grid->vertices += 1;
116 }
117 
igraph_2dgrid_add2(igraph_2dgrid_t * grid,long int elem)118 void igraph_2dgrid_add2(igraph_2dgrid_t *grid, long int elem) {
119     long int x, y;
120     long int first;
121     igraph_real_t xc, yc;
122 
123     xc = MATRIX(*grid->coords, elem, 0);
124     yc = MATRIX(*grid->coords, elem, 1);
125 
126     /* add to cell */
127     igraph_2dgrid_which(grid, xc, yc, &x, &y);
128     first = (long int) MATRIX(grid->startidx, x, y);
129     VECTOR(grid->prev)[elem] = 0;
130     VECTOR(grid->next)[elem] = first;
131     if (first != 0) {
132         VECTOR(grid->prev)[first - 1] = elem + 1;
133     }
134     MATRIX(grid->startidx, x, y) = elem + 1;
135 
136     grid->massx += xc;
137     grid->massy += yc;
138     grid->vertices += 1;
139 }
140 
igraph_2dgrid_move(igraph_2dgrid_t * grid,long int elem,igraph_real_t xc,igraph_real_t yc)141 void igraph_2dgrid_move(igraph_2dgrid_t *grid, long int elem,
142                         igraph_real_t xc, igraph_real_t yc) {
143     long int oldx, oldy;
144     long int newx, newy;
145     igraph_real_t oldxc = MATRIX(*grid->coords, elem, 0);
146     igraph_real_t oldyc = MATRIX(*grid->coords, elem, 1);
147     long int first;
148 
149     xc = oldxc + xc; yc = oldyc + yc;
150 
151     igraph_2dgrid_which(grid, oldxc, oldyc, &oldx, &oldy);
152     igraph_2dgrid_which(grid, xc, yc, &newx, &newy);
153     if (oldx != newx || oldy != newy) {
154         /* remove from this cell */
155         if (VECTOR(grid->prev)[elem] != 0) {
156             VECTOR(grid->next) [ (long int) VECTOR(grid->prev)[elem] - 1 ] =
157                 VECTOR(grid->next)[elem];
158         } else {
159             MATRIX(grid->startidx, oldx, oldy) = VECTOR(grid->next)[elem];
160         }
161         if (VECTOR(grid->next)[elem] != 0) {
162             VECTOR(grid->prev)[ (long int) VECTOR(grid->next)[elem] - 1 ] =
163                 VECTOR(grid->prev)[elem];
164         }
165 
166         /* add to this cell */
167         first = (long int) MATRIX(grid->startidx, newx, newy);
168         VECTOR(grid->prev)[elem] = 0;
169         VECTOR(grid->next)[elem] = first;
170         if (first != 0) {
171             VECTOR(grid->prev)[first - 1] = elem + 1;
172         }
173         MATRIX(grid->startidx, newx, newy) = elem + 1;
174     }
175 
176     grid->massx += -oldxc + xc;
177     grid->massy += -oldyc + yc;
178 
179     MATRIX(*grid->coords, elem, 0) = xc;
180     MATRIX(*grid->coords, elem, 1) = yc;
181 
182 }
183 
igraph_2dgrid_getcenter(const igraph_2dgrid_t * grid,igraph_real_t * massx,igraph_real_t * massy)184 void igraph_2dgrid_getcenter(const igraph_2dgrid_t *grid,
185                              igraph_real_t *massx, igraph_real_t *massy) {
186     *massx = (grid->massx) / (grid->vertices);
187     *massy = (grid->massy) / (grid->vertices);
188 }
189 
igraph_2dgrid_in(const igraph_2dgrid_t * grid,long int elem)190 igraph_bool_t igraph_2dgrid_in(const igraph_2dgrid_t *grid, long int elem) {
191     return VECTOR(grid->next)[elem] != -1;
192 }
193 
igraph_2dgrid_dist(const igraph_2dgrid_t * grid,long int e1,long int e2)194 igraph_real_t igraph_2dgrid_dist(const igraph_2dgrid_t *grid,
195                                  long int e1, long int e2) {
196     igraph_real_t x = MATRIX(*grid->coords, e1, 0) - MATRIX(*grid->coords, e2, 0);
197     igraph_real_t y = MATRIX(*grid->coords, e1, 1) - MATRIX(*grid->coords, e2, 1);
198 
199     return sqrt(x * x + y * y);
200 }
201 
igraph_2dgrid_dist2(const igraph_2dgrid_t * grid,long int e1,long int e2)202 igraph_real_t igraph_2dgrid_dist2(const igraph_2dgrid_t *grid,
203                                   long int e1, long int e2) {
204     igraph_real_t x = MATRIX(*grid->coords, e1, 0) - MATRIX(*grid->coords, e2, 0);
205     igraph_real_t y = MATRIX(*grid->coords, e1, 1) - MATRIX(*grid->coords, e2, 1);
206 
207     return x * x + y * y;
208 }
209 
igraph_i_2dgrid_addvertices(igraph_2dgrid_t * grid,igraph_vector_t * eids,igraph_integer_t vid,igraph_real_t r,long int x,long int y)210 int igraph_i_2dgrid_addvertices(igraph_2dgrid_t *grid, igraph_vector_t *eids,
211                                 igraph_integer_t vid, igraph_real_t r,
212                                 long int x, long int y) {
213     long int act;
214     igraph_real_t *v = VECTOR(grid->next);
215 
216     r = r * r;
217     act = (long int) MATRIX(grid->startidx, x, y);
218     while (act != 0) {
219         if (igraph_2dgrid_dist2(grid, vid, act - 1) < r) {
220             IGRAPH_CHECK(igraph_vector_push_back(eids, act - 1));
221         }
222         act = (long int) v[act - 1];
223     }
224     return 0;
225 }
226 
igraph_2dgrid_neighbors(igraph_2dgrid_t * grid,igraph_vector_t * eids,igraph_integer_t vid,igraph_real_t r)227 int igraph_2dgrid_neighbors(igraph_2dgrid_t *grid, igraph_vector_t *eids,
228                             igraph_integer_t vid, igraph_real_t r) {
229     igraph_real_t xc = MATRIX(*grid->coords, (long int)vid, 0);
230     igraph_real_t yc = MATRIX(*grid->coords, (long int)vid, 1);
231     long int x, y;
232     igraph_vector_clear(eids);
233 
234     igraph_2dgrid_which(grid, xc, yc, &x, &y);
235 
236     /* this cell */
237     igraph_i_2dgrid_addvertices(grid, eids, vid, r, x, y);
238 
239     /* left */
240     if (x != 0) {
241         igraph_i_2dgrid_addvertices(grid, eids, vid, r, x - 1, y);
242     }
243     /* right */
244     if (x != grid->stepsx - 1) {
245         igraph_i_2dgrid_addvertices(grid, eids, vid, r, x + 1, y);
246     }
247     /* up */
248     if (y != 0) {
249         igraph_i_2dgrid_addvertices(grid, eids, vid, r, x, y - 1);
250     }
251     /* down */
252     if (y != grid->stepsy - 1) {
253         igraph_i_2dgrid_addvertices(grid, eids, vid, r, x, y + 1);
254     }
255     /* up & left */
256     if (x != 0 && y != 0) {
257         igraph_i_2dgrid_addvertices(grid, eids, vid, r, x - 1, y - 1);
258     }
259     /* up & right */
260     if (x != grid->stepsx - 1 && y != 0) {
261         igraph_i_2dgrid_addvertices(grid, eids, vid, r, x + 1, y - 1);
262     }
263     /* down & left */
264     if (x != 0 && y != grid->stepsy - 1) {
265         igraph_i_2dgrid_addvertices(grid, eids, vid, r, x - 1, y + 1);
266     }
267     /* down & right */
268     if (x != grid->stepsx - 1 && y != grid->stepsy - 1) {
269         igraph_i_2dgrid_addvertices(grid, eids, vid, r, x - 1, y + 1);
270     }
271 
272     return 0;
273 }
274 
igraph_2dgrid_reset(igraph_2dgrid_t * grid,igraph_2dgrid_iterator_t * it)275 void igraph_2dgrid_reset(igraph_2dgrid_t *grid, igraph_2dgrid_iterator_t *it) {
276     /* Search for the first cell containing a vertex */
277     it->x = 0; it->y = 0; it->vid = (long int) MATRIX(grid->startidx, 0, 0);
278     while ( it->vid == 0 && (it->x < grid->stepsx - 1 || it->y < grid->stepsy - 1)) {
279         it->x += 1;
280         if (it->x == grid->stepsx) {
281             it->x = 0; it->y += 1;
282         }
283         it->vid = (long int) MATRIX(grid->startidx, it->x, it->y);
284     }
285 }
286 
igraph_2dgrid_next(igraph_2dgrid_t * grid,igraph_2dgrid_iterator_t * it)287 igraph_integer_t igraph_2dgrid_next(igraph_2dgrid_t *grid,
288                                     igraph_2dgrid_iterator_t *it) {
289     long int ret = it->vid;
290 
291     if (ret == 0) {
292         return 0;
293     }
294 
295     /* First neighbor */
296     it->ncells = -1;
297     if (it->x != grid->stepsx - 1) {
298         it->ncells += 1;
299         it->nx[it->ncells] = it->x + 1;
300         it->ny[it->ncells] = it->y;
301     }
302     if (it->y != grid->stepsy - 1) {
303         it->ncells += 1;
304         it->nx[it->ncells] = it->x;
305         it->ny[it->ncells] = it->y + 1;
306     }
307     if (it->ncells == 1) {
308         it->ncells += 1;
309         it->nx[it->ncells] = it->x + 1;
310         it->ny[it->ncells] = it->y + 1;
311     }
312     it->ncells += 1;
313     it->nx[it->ncells] = it->x;
314     it->ny[it->ncells] = it->y;
315 
316     it->nei = (long int) VECTOR(grid->next) [ ret - 1 ];
317     while (it->ncells > 0 && it->nei == 0 ) {
318         it->ncells -= 1;
319         it->nei = (long int) MATRIX(grid->startidx, it->nx[it->ncells], it->ny[it->ncells]);
320     }
321 
322     /* Next vertex */
323     it->vid = (long int) VECTOR(grid->next)[ it->vid - 1 ];
324     while ( (it->x < grid->stepsx - 1 || it->y < grid->stepsy - 1) &&
325             it->vid == 0) {
326         it->x += 1;
327         if (it->x == grid->stepsx) {
328             it->x = 0; it->y += 1;
329         }
330         it->vid = (long int) MATRIX(grid->startidx, it->x, it->y);
331     }
332 
333     return (igraph_integer_t) ret;
334 }
335 
igraph_2dgrid_next_nei(igraph_2dgrid_t * grid,igraph_2dgrid_iterator_t * it)336 igraph_integer_t igraph_2dgrid_next_nei(igraph_2dgrid_t *grid,
337                                         igraph_2dgrid_iterator_t *it) {
338     long int ret = it->nei;
339 
340     if (it->nei != 0) {
341         it->nei = (long int) VECTOR(grid->next) [ ret - 1 ];
342     }
343     while (it->ncells > 0 && it->nei == 0 ) {
344         it->ncells -= 1;
345         it->nei = (long int) MATRIX(grid->startidx, it->nx[it->ncells], it->ny[it->ncells]);
346     }
347 
348     return (igraph_integer_t) ret;
349 }
350 
351 /*-----------------------------------------------------------------------*/
352 
igraph_i_layout_mergegrid_which(igraph_i_layout_mergegrid_t * grid,igraph_real_t xc,igraph_real_t yc,long int * x,long int * y)353 int igraph_i_layout_mergegrid_which(igraph_i_layout_mergegrid_t *grid,
354                                     igraph_real_t xc, igraph_real_t yc,
355                                     long int *x, long int *y) {
356     if (xc <= grid->minx) {
357         *x = 0;
358     } else if (xc >= grid->maxx) {
359         *x = grid->stepsx - 1;
360     } else {
361         *x = (long int) floor((xc - (grid->minx)) / (grid->deltax));
362     }
363 
364     if (yc <= grid->miny) {
365         *y = 0;
366     } else if (yc >= grid->maxy) {
367         *y = grid->stepsy - 1;
368     } else {
369         *y = (long int) floor((yc - (grid->miny)) / (grid->deltay));
370     }
371 
372     return 0;
373 }
374 
igraph_i_layout_mergegrid_init(igraph_i_layout_mergegrid_t * grid,igraph_real_t minx,igraph_real_t maxx,long int stepsx,igraph_real_t miny,igraph_real_t maxy,long int stepsy)375 int igraph_i_layout_mergegrid_init(igraph_i_layout_mergegrid_t *grid,
376                                    igraph_real_t minx, igraph_real_t maxx, long int stepsx,
377                                    igraph_real_t miny, igraph_real_t maxy, long int stepsy) {
378     grid->minx = minx;
379     grid->maxx = maxx;
380     grid->stepsx = stepsx;
381     grid->deltax = (maxx - minx) / stepsx;
382     grid->miny = miny;
383     grid->maxy = maxy;
384     grid->stepsy = stepsy;
385     grid->deltay = (maxy - miny) / stepsy;
386 
387     grid->data = igraph_Calloc(stepsx * stepsy, long int);
388     if (grid->data == 0) {
389         IGRAPH_ERROR("Cannot create grid", IGRAPH_ENOMEM);
390     }
391     return 0;
392 }
393 
igraph_i_layout_mergegrid_destroy(igraph_i_layout_mergegrid_t * grid)394 void igraph_i_layout_mergegrid_destroy(igraph_i_layout_mergegrid_t *grid) {
395     igraph_Free(grid->data);
396 }
397 
398 #define MAT(i,j) (grid->data[(grid->stepsy)*(j)+(i)])
399 #define DIST2(x2,y2) (sqrt(pow(x-(x2),2)+pow(y-(y2), 2)))
400 
igraph_i_layout_merge_place_sphere(igraph_i_layout_mergegrid_t * grid,igraph_real_t x,igraph_real_t y,igraph_real_t r,long int id)401 int igraph_i_layout_merge_place_sphere(igraph_i_layout_mergegrid_t *grid,
402                                        igraph_real_t x, igraph_real_t y, igraph_real_t r,
403                                        long int id) {
404     long int cx, cy;
405     long int i, j;
406 
407     igraph_i_layout_mergegrid_which(grid, x, y, &cx, &cy);
408 
409     MAT(cx, cy) = id + 1;
410 
411 #define DIST(i,j) (DIST2(grid->minx+(cx+(i))*grid->deltax, \
412                          grid->miny+(cy+(j))*grid->deltay))
413 
414     for (i = 0; cx + i < grid->stepsx && DIST(i, 0) < r; i++) {
415         for (j = 0; cy + j < grid->stepsy && DIST(i, j) < r; j++) {
416             MAT(cx + i, cy + j) = id + 1;
417         }
418     }
419 
420 #undef DIST
421 #define DIST(i,j) (DIST2(grid->minx+(cx+(i))*grid->deltax, \
422                          grid->miny+(cy-(j)+1)*grid->deltay))
423 
424     for (i = 0; cx + i < grid->stepsx && DIST(i, 0) < r; i++) {
425         for (j = 1; cy - j > 0 && DIST(i, j) < r; j++) {
426             MAT(cx + i, cy - j) = id + 1;
427         }
428     }
429 
430 #undef DIST
431 #define DIST(i,j) (DIST2(grid->minx+(cx-(i)+1)*grid->deltax, \
432                          grid->miny+(cy+(j))*grid->deltay))
433 
434     for (i = 1; cx - i > 0 && DIST(i, 0) < r; i++) {
435         for (j = 0; cy + j < grid->stepsy && DIST(i, j) < r; j++) {
436             MAT(cx - i, cy + j) = id + 1;
437         }
438     }
439 
440 #undef DIST
441 #define DIST(i,j) (DIST2(grid->minx+(cx-(i)+1)*grid->deltax, \
442                          grid->miny+(cy-(j)+1)*grid->deltay))
443 
444     for (i = 1; cx - i > 0 && DIST(i, 0) < r; i++) {
445         for (j = 1; cy - j > 0 && DIST(i, j) < r; j++) {
446             MAT(cx - i, cy - j) = id + 1;
447         }
448     }
449 
450 #undef DIST
451 #undef DIST2
452 
453     return 0;
454 }
455 
igraph_i_layout_mergegrid_get(igraph_i_layout_mergegrid_t * grid,igraph_real_t x,igraph_real_t y)456 long int igraph_i_layout_mergegrid_get(igraph_i_layout_mergegrid_t *grid,
457                                        igraph_real_t x, igraph_real_t y) {
458     long int cx, cy;
459     long int res;
460 
461     if (x <= grid->minx || x >= grid->maxx ||
462         y <= grid->miny || y >= grid->maxy) {
463         res = -1;
464     } else {
465         igraph_i_layout_mergegrid_which(grid, x, y, &cx, &cy);
466         res = MAT(cx, cy) - 1;
467     }
468 
469     return res;
470 }
471 
472 #define DIST2(x2,y2) (sqrt(pow(x-(x2),2)+pow(y-(y2), 2)))
473 
igraph_i_layout_mergegrid_get_sphere(igraph_i_layout_mergegrid_t * grid,igraph_real_t x,igraph_real_t y,igraph_real_t r)474 long int igraph_i_layout_mergegrid_get_sphere(igraph_i_layout_mergegrid_t *grid,
475         igraph_real_t x, igraph_real_t y, igraph_real_t r) {
476     long int cx, cy;
477     long int i, j;
478     long int ret;
479 
480     if (x - r <= grid->minx || x + r >= grid->maxx ||
481         y - r <= grid->miny || y + r >= grid->maxy) {
482         ret = -1;
483     } else {
484         igraph_i_layout_mergegrid_which(grid, x, y, &cx, &cy);
485 
486         ret = MAT(cx, cy) - 1;
487 
488 #define DIST(i,j) (DIST2(grid->minx+(cx+(i))*grid->deltax, \
489                          grid->miny+(cy+(j))*grid->deltay))
490 
491         for (i = 0; ret < 0 && cx + i < grid->stepsx && DIST(i, 0) < r; i++) {
492             for (j = 0; ret < 0 && cy + j < grid->stepsy && DIST(i, j) < r; j++) {
493                 ret = MAT(cx + i, cy + j) - 1;
494             }
495         }
496 
497 #undef DIST
498 #define DIST(i,j) (DIST2(grid->minx+(cx+(i))*grid->deltax, \
499                          grid->miny+(cy-(j)+1)*grid->deltay))
500 
501         for (i = 0; ret < 0 && cx + i < grid->stepsx && DIST(i, 0) < r; i++) {
502             for (j = 1; ret < 0 && cy - j > 0 && DIST(i, j) < r; j++) {
503                 ret = MAT(cx + i, cy - j) - 1;
504             }
505         }
506 
507 #undef DIST
508 #define DIST(i,j) (DIST2(grid->minx+(cx-(i)+1)*grid->deltax, \
509                          grid->miny+(cy+(j))*grid->deltay))
510 
511         for (i = 1; ret < 0 && cx - i > 0 && DIST(i, 0) < r; i++) {
512             for (j = 0; ret < 0 && cy + j < grid->stepsy && DIST(i, j) < r; j++) {
513                 ret = MAT(cx - i, cy + j) - 1;
514             }
515         }
516 
517 #undef DIST
518 #define DIST(i,j) (DIST2(grid->minx+(cx-(i)+1)*grid->deltax, \
519                          grid->miny+(cy-(j)+1)*grid->deltay))
520 
521         for (i = 1; ret < 0 && cx + i > 0 && DIST(i, 0) < r; i++) {
522             for (j = 1; ret < 0 && cy + i > 0 && DIST(i, j) < r; j++) {
523                 ret = MAT(cx - i, cy - j) - 1;
524             }
525         }
526 
527 #undef DIST
528 
529     }
530 
531     return ret;
532 }
533 
534 /* int print_grid(igraph_i_layout_mergegrid_t *grid) { */
535 /*   long int i,j; */
536 
537 /*   for (i=0; i<grid->stepsx; i++) { */
538 /*     for (j=0; j<grid->stepsy; j++) { */
539 /*       printf("%li ", MAT(i,j)-1); */
540 /*     } */
541 /*     printf("\n"); */
542 /*   } */
543 /* } */
544