31#ifndef _CMGRAPHS_MATCHARR_H_
32#define _CMGRAPHS_MATCHARR_H_
46#include "chomp/system/config.h"
47#include "chomp/system/textfile.h"
58template <
class CoordType,
class IntType>
66 const CoordType *_corner = 0);
72 void join (
const CoordType *x,
const CoordType *y);
77 bool joined (
const CoordType *x,
const CoordType *y)
const;
82 template <
class CubeType>
83 void saveClasses (std::vector<std::vector<CubeType> > &matchClasses)
146 void saveSet (
const char *prefix,
int counter,
int pos,
147 CoordType *workspace,
int ndigits)
const;
150 void join (IntType xpos, IntType ypos);
156template <
class CoordType,
class IntType>
158 const CoordType *_sizes,
const CoordType *_corner):
159 link1 (0), link2 (0), num (0), sizes (0), corner (0),
160 dim (_dim), length (0)
163 throw "Undefined array sizes.";
165 throw "Non-positive dimension.";
168 for (
int i = 0; i <
dim; ++ i)
170 sizes [i] = _sizes [i];
174 throw "Too large matching array requested.";
179 for (
int i = 0; i <
dim; ++ i)
185 for (
int offset = 0; offset <
length; ++ offset)
187 num [offset] = offset;
194 CoordType *c =
new CoordType [
dim];
195 for (
int i = 0; i <
dim; ++ i)
197 for (
int offset = 0; offset <
length; ++ offset)
201 chomp::homology::sbug <<
"Mismatch at "
202 "array offset " << offset <<
208 if (++ c [i] <
sizes [i] +
225template <
class CoordType,
class IntType>
237template <
class CoordType,
class IntType>
241 throw "Array assignment operator not allowed.";
245template <
class CoordType,
class IntType>
249 throw "Array copy constructor not allowed.";
255template <
class CoordType,
class IntType>
260 for (
int i = 0; i < dim - 1; ++ i)
262 x [i] = n % sizes [i] + (corner ? corner [i] : 0);
265 x [dim - 1] = n % sizes [dim - 1] + (corner ? corner [dim - 1] : 0);
269template <
class CoordType,
class IntType>
271 (
const CoordType *x)
const
273 IntType n = x [dim - 1] - (corner ? corner [dim - 1] : 0);
274 for (
int i = dim - 2; i >= 0; -- i)
277 n += x [i] - (corner ? corner [i] : 0);
282template <
class CoordType,
class IntType>
285 if (num [xpos] == num [ypos])
287 IntType newnum = num [xpos];
288 while (link1 [xpos] >= 0)
290 while (link2 [ypos] >= 0)
297 if (link1 [ypos] < 0)
306template <
class CoordType,
class IntType>
308 int counter,
int pos, CoordType *workspace,
int ndigits)
const
311 std::ostringstream fname;
314 for (
int i = 1; i < ndigits; ++ i)
316 while (counter < ten)
321 fname << counter <<
".cub";
322 std::ofstream out (fname. str (). c_str ());
325 while (link1 [pos] >= 0)
331 link2coords (pos, workspace);
332 for (
int i = 0; i < dim; ++ i)
333 out << (i ?
"," :
"(") << workspace [i];
354template <
class CoordType,
class IntType>
358 join (coords2link (x), coords2link (y));
362template <
class CoordType,
class IntType>
364 const CoordType *y)
const
366 int xpos = coords2link (x);
369 int ypos = coords2link (y);
372 return (num [xpos] == num [ypos]);
375template <
class CoordType,
class IntType>
380 chomp::homology::sbug <<
"Analyzing the sets of matched boxes... ";
381 for (IntType cur = 0; cur < length; ++ cur)
383 if ((link1 [cur] < 0) && (link2 [cur] >= 0))
392 chains. push_back (
pair2 (cur, setsize));
395 chomp::homology::sbug << chains. size () <<
" nontrivial classes.\n";
398 std::sort (chains. begin (), chains. end ());
403template <
class CoordType,
class IntType>
408 std::vector<pair2> sets;
409 this -> getChains (sets);
414 while (sets. size () >= ten)
422 chomp::homology::sbug <<
"Saving the nontrivial "
423 "equivalence classes... ";
424 CoordType *workspace =
new CoordType [dim];
425 for (
int i = sets. size () - 1; i >= 0; -- i)
427 saveSet (prefix, ++ counter, sets [i]. x, workspace,
431 chomp::homology::sout <<
"Done.\n";
436template <
class CoordType,
class IntType>
437template <
class CubeType>
439 (std::vector<std::vector<CubeType> > &matchClasses)
const
442 std::vector<pair2> sets;
446 CoordType *coord =
new CoordType [dim];
447 std::vector<CubeType> emptyVector;
448 for (
int i = sets. size () - 1; i >= 0; -- i)
451 IntType pos = sets [i]. x;
452 while (link1 [pos] >= 0)
456 matchClasses. push_back (emptyVector);
457 std::vector<CubeType> &vect =
458 matchClasses [matchClasses. size () - 1];
459 vect. resize (sets [i]. value);
463 link2coords (pos, coord);
464 vect [j ++] = CubeType (coord, dim);
A multi-dimensional array with links forward/backward between the entries.
void saveSet(const char *prefix, int counter, int pos, CoordType *workspace, int ndigits) const
Saves one set to a file.
MatchArray(int _dim, const CoordType *_sizes, const CoordType *_corner=0)
The only allowed constructor in which the size of the array and its dimension must be given.
void link2coords(IntType link, CoordType *x) const
Translates a flat offset array into a multidimensional one.
void saveSets(const char *prefix) const
Saves the sets to separate files. Sorts the sets by their size.
IntType * link2
Forward links for chains.
IntType * link1
Backward links for chains.
void join(IntType xpos, IntType ypos)
Joins two sets, given the offsets in the flat arrays.
MatchArray & operator=(const MatchArray< CoordType, IntType > &a)
The assignment operator is not allowed.
IntType * num
The unique number for each chain.
void saveClasses(std::vector< std::vector< CubeType > > &matchClasses) const
Saves the equivalence classes larger than 1 element to the provided vector of vectors (the classes ar...
MatchArray(const MatchArray< CoordType, IntType > &a)
The copy constructor is not allowed.
int length
The length of the allocated memory arrays.
~MatchArray()
The destructor.
CoordType * corner
The coordinates of the minimal corner of the array if any.
IntType coords2link(const CoordType *x) const
Computes the memory offset that corresponds to the given multidimensional position in the array.
void join(const CoordType *x, const CoordType *y)
Joins the chains corresponding to the two parameter n-tuples.
int dim
The dimension of the array.
CoordType * sizes
The size of the multi-dimensional array in each direction.
void getChains(std::vector< MatchArray< CoordType, IntType >::pair2 > &chains) const
Retrieves a set of first elements of all the chains which have at least two elements.
bool joined(const CoordType *x, const CoordType *y) const
Checks if the two parameters have already been joined, that is, if they belong to the same chain.
A small class whose objects store an IntType object and an int value.
pair2(IntType _x, int _value)
bool operator<(const pair2 &other) const