There are a few things you need to do to accomplish what you want. First, given the division count, we must separate the two-dimensional space. Secondly, using the division count, we need a flexible method of grouping fixations into their corresponding points. Finally, we generate any statistics you need.
As for the number of divisions, the built-in FactorInteger function almost does what you need. For instance,
(* The second parameter is the upper limit for the number of factors returned *) FactorInteger[35,2] == {{5,1}, {7,1}} FactorInteger[64,2] == {{2,6}}
Unfortunately, you can specify only the upper limit of the number of returned factors, so we need to slightly change the result
Clear[divisionCount] divisionCount[c_Integer?(Positive[
This does two things, replaces {{b,m}} with {{b, m / 2 + m mod 2}, {b, m / 2}} , where / represents integer division (that is, there are residues) and converts {{b, m} ..} to {b^m ..} via Power @@@ . This gives
divisionCount[32] == {8, 4} divisionCount[64] == {8, 8}.
It turns out that we can get a fixation account at this point with minimal additional work through BinCounts as follows
BinCounts[fix[[All,;;2]], (* stripping duration from tuples *) {xmin, xmax, (xmax - xmin)/#1, {ymin, ymax, (ymax - ymin)/
where you need to specify ranges for x and y and the number of divisions. However, this is not as flexible as it could be. Instead, we will use SelectEquivalents .
The key to using SelectEquivalents effectively is to create a good categorization function. To do this, we need to determine the divisions themselves, as follows
Clear[makeDivisions] makeDivisions[ {xmin_, xmax_, xdivs_Integer?Positive}, {ymin_, ymax_, ydivs_Integer?Positive}] := Partition[
Where
makeDivisions[{0, 1}, {0, 1}, 6] == {{{0, 1/3}, {1/3, 2/3}, {2/3, 1}}, {{0, 1/2}, {1/2, 1}}}.
(I would use FindDivisions , but it does not always return the number of queries you request.) makeDivisions returns two lists, where each member in each list is a min-max pair, which we can use to determine if a point falls into the cell .
Since we are on a square grid, we need to check all the pairs of limits that we just defined. I would use the following
Clear[inBinQ, categorize] inBinQ[{xmin_,xmax_}, {ymin_, ymax_}, {x_,y_}]:= (xmin <= x < xmax) && (ymin <= y < ymax) categorize[{xmin_, xmax_}, {ymin_, ymax_}, divs_][val : {x_, y_, t_}] := With[{bins = makeDivisions[{xmin, xmax}, {ymin, ymax}, divs]}, Outer[inBinQ[#1, #2, {x, y}] &, bins[[1]], bins[[2]], 1]] //Transpose
which returns
categorize[{0,1},{0,1},6][{0.1, 0.2, 5}] == {{True, False, False}, {False, False, False}}.
Please note that the y-coordinate is inverted compared to the graph, low values are at the beginning of the array. To “fix” this, Reverse bins[[2]] in categorize . In addition, you will want to remove Transpose before submitting the results to MatrixPlot , as it expects results in untransformed form.
Using
SelectEquivalents[ fix, (categorize[{xmin, xmax}, {ymin, ymax}, 6][#] /. {True -> 1, False -> 0} &), #[[3]] &, (* strip off all but the timing data *) {#1, #2} &],
we get
{{ {{0, 0, 0}, {0, 1, 0}}, {774., 518., 161., 121., 273., 177., 217., 406.} }, { {{0, 0, 0}, {0, 0, 1}}, {200., 236.} }, { {{0, 0, 1}, {0, 0, 0}}, {176., 154.} }, { {{0, 1, 0}, {0, 0, 0}}, {124., 119., 366.} }}}
where the first term in each sublist is the matrix representation of the hopper, and the second term is a list of points that fall into this bit. To determine how many are in each box,
Plus @@ (Times @@@ ({
Or timings
Plus @@ (Times @@@ ({
Change As you can see, to get any statistics needed for commits, you just need to replace either Length or Total . For example, you may need Mean Time, not just General.