Collection Collection_and_Permutation_permuteItems (Collection me, Permutation him) { try { if (my size != his numberOfElements) { Melder_throw (me, "The number of elements are not equal."); } autoNUMvector<long> pos (1, my size); autoCollection thee = static_cast<Collection> (Data_copy (me)); for (long i = 1; i <= my size; i++) { pos[i] = i; } /* Dual meaning of array pos: */ /* k < i : position of item 'k' */ /* k >= i : the item at position 'k' */ for (long i = 1; i <= my size; i++) { long ti = pos[i], which = Permutation_getValueAtIndex (him, i); long where = pos[which]; /* where >= i */ Data tmp = static_cast<Data> (thy item[i]); if (i == where) { continue; } thy item[i] = thy item[ where ]; thy item[where] = tmp; /* order is important !! */ pos[ti] = where; pos[where] = ti; pos[which] = which <= i ? i : ti; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, ": not permuted."); } }
Permutation Permutation_permuteBlocksRandomly (Permutation me, long from, long to, long blocksize, int permuteWithinBlocks, int noDoublets) { try { long n = Permutation_checkRange (me, &from, &to); if (blocksize == 1 || (blocksize >= n && permuteWithinBlocks)) { autoPermutation thee = Permutation_permuteRandomly (me, from, to); return thee.transfer(); } autoPermutation thee = Data_copy (me); if (blocksize >= n) { return thee.transfer(); } long nblocks = n / blocksize, nrest = n % blocksize; if (nrest != 0) Melder_throw ("It is not possible to fit an integer number of blocks " "in the range.\n(The last block is only of size ", nrest, ")."); autoPermutation pblocks = Permutation_create (nblocks); Permutation_permuteRandomly_inline (pblocks.peek(), 1, nblocks); long first = from; for (long iblock = 1; iblock <= nblocks; iblock++, first += blocksize) { /* (n1,n2,n3,...) means: move block n1 to position 1 etc... */ long blocktomove = Permutation_getValueAtIndex (pblocks.peek(), iblock); for (long j = 1; j <= blocksize; j++) { thy p[first - 1 + j] = my p[from - 1 + (blocktomove - 1) * blocksize + j]; } if (permuteWithinBlocks) { long last = first + blocksize - 1; Permutation_permuteRandomly_inline (thee.peek(), first, last); if (noDoublets && iblock > 0 && (thy p[first - 1] % blocksize) == (thy p[first] % blocksize)) { Permutation_swapOneFromRange (thee.peek(), first + 1, last, first, 0); } } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, ": not permuted block randomly."); } }
void Graphics_matrixAsSquares (Graphics g, double **matrix, long numberOfRows, long numberOfColumns, double zmin, double zmax, double cellSizeFactor, int randomFillOrder) { long numberOfCells = numberOfRows * numberOfColumns; autoPermutation p = Permutation_create (numberOfCells); if (randomFillOrder) { Permutation_permuteRandomly_inline (p.peek(), 1, numberOfCells); } double zAbsMax = fabs (zmax) > fabs (zmin) ? fabs (zmax) : fabs (zmin); Graphics_Colour colour = Graphics_inqColour (g); double x1WC, x2WC, y1WC, y2WC; Graphics_inqWindow (g, &x1WC, &x2WC, &y1WC, &y2WC); double dx = fabs (x2WC - x1WC) / numberOfColumns; double dy = fabs (y2WC - y1WC) / numberOfRows; for (long i = 1; i <= numberOfCells; i++) { long index = Permutation_getValueAtIndex (p.peek(), i); long irow = (index - 1) / numberOfColumns + 1; long icol = (index - 1) % numberOfColumns + 1; double z = matrix[irow][icol]; z = z < zmin ? zmin : z; z = z > zmax ? zmax : z; double zweight = sqrt (fabs (z) / zAbsMax); // Area length^2) double xcenter = (icol - 0.5) * dx; double ycenter = (irow - 0.5) * dy; double x1 = x1WC + xcenter - zweight * 0.5 * dx * cellSizeFactor; x1 = x1 < x1WC ? x1WC : x1; double x2 = x1WC + xcenter + zweight * 0.5 * dx * cellSizeFactor; x2 = x2 > x2WC ? x2WC : x2; double y1 = y1WC + ycenter - zweight * 0.5 * dy * cellSizeFactor; y1 = y1 < y1WC ? y1WC : y1; double y2 = y1WC + ycenter + zweight * 0.5 * dy * cellSizeFactor; y2 = y2 > y2WC ? y2WC : y2; if (z > 0) { Graphics_setColour (g, Graphics_WHITE); } Graphics_fillRectangle (g, x1, x2, y1, y2); Graphics_setColour (g, colour); Graphics_rectangle (g, x1, x2 , y1, y2); } }