Group Abstract Group Abstract

Message Boards Message Boards

[CALL] SpacePartition: design and applications

This is a call for some feedback on a small utility function I am trying to design. A few times I felt the need in a continuous partitioning of space. Could you please, after reading the post, give me some feedback on:

  • What other applications this function can be used for? (Especially higher-dimensional cases)
  • Do you have a better design suggestions?

Definition

The SpacePartition function is a continuous analog of Partition. It subdivides n-dimensional space into integer number of partitions. The result is a tensor of hyper-blocks spanning the hyperspace without gaps or overlaps. It means currently, and for simplicity of the demo, there are no block offsets, but they could be added in the future.

SpacePartition[space_List, partitions_List] :=
  Outer[List, ##, 1] & @@ MapThread[Partition[Subdivide @@ Append[#1, #2], 2, 1] &, {space, partitions}]

1D Examples

Subdividing 1D interval {2.3,5.7} into 5 consecutive intervals:

part1D = SpacePartition[{{2.3, 5.7}}, {5}]

{{{2.3, 2.98}}, {{2.98, 3.66}}, {{3.66, 4.34}}, {{4.34, 5.02}}, {{5.02, 5.7}}}

NumberLinePlot[Interval @@@ part1D]

enter image description here

2D Examples

Subdividing 2D rectangle into different number of partitions along different dimensions

part2D = SpacePartition[{{2.3, 5.7}, {1.2, 3.4}}, {7, 5}];

and visualizing as a grid

Graphics[grid2D = {FaceForm[], EdgeForm[Black], Rectangle @@ Transpose[#]} & /@ 
Flatten[part2D, 1], Frame -> True]

enter image description here

Subdivisions preserve the neighborhood structure

Graphics[{grid2D, {Opacity[.5], Rectangle @@ Transpose[#]} & /@ 
(part2D[[##]] & @@@ Tuples[{1, 2, 3}, 2])}, Frame -> True]

enter image description here

3D Examples

Subdividing 3D rectangle into different number of partitions along different dimensions

part3D = SpacePartition[{{2.3, 5.7}, {1.2, 3.4}, {-1.1, 2}}, {7, 5, 4}];

and visualizing as a 3D grid

Graphics3D[{Opacity[.6], Cuboid @@ Transpose[#]} & /@ Flatten[part3D, 2], Axes -> True]

enter image description here

Selecting random subsets of subdivisions as Region:

Table[Show[Region[Cuboid @@ Transpose[#]] & /@ 
RandomSample[Flatten[part3D, 2], 20], Axes -> True, Boxed -> True],3]

enter image description here

Application: quarterly temperatures or partitioning PlotRange

Often data are so dense it is hard to distinguish details in a standard plot.

data = WeatherData["KMDZ", "Temperature", {{2015}}];
plot = DateListPlot[data]

enter image description here

SpacePartition can be used to partition PlotRange and make a better visual

With[{pr = PlotRange /. Options[plot]},
  DateListPlot[TimeSeriesWindow[data, #], AspectRatio -> 1/10, ImageSize -> 1000,
     PlotRange -> {Automatic, {-30, 30}}, Filling -> Axis, PlotTheme -> "Detailed"] & /@
      Map[DateList, Flatten[SpacePartition[{pr[[1]]}, {4}], 1], {2}]] // Column

enter image description here

Application: box-counting method for fractal measures

Define an iterated function system (IFS) and iterate it on point sets

IFS[{T__TransformationFunction}][pl_List] := Join @@ Through[{T}[pl]]
IFSNest[f_IFS, pts_, n_Integer] := Nest[f, pts, n]

Sierpi?ski gasket transformation:

SierpinskiGasket = With[{\[ScriptCapitalD] = DiagonalMatrix[{1, 1}/2]},
   IFS[{AffineTransform[{\[ScriptCapitalD]}], 
     AffineTransform[{\[ScriptCapitalD], {1/2, 0}}], 
     AffineTransform[{\[ScriptCapitalD], {0.25, 0.433}}]}]];

and corresponding iterated point set

ptsSierp = IFSNest[N@SierpinskiGasket, RandomReal[1, {100, 2}], 4];
graSierp = Graphics[{PointSize[Tiny], Point[ptsSierp]}, Frame -> True]

enter image description here

Function that makes partitions

blocks[n_]:=Rectangle@@Transpose[#]&/@Flatten[N@SpacePartition[{{0,1},{0,1}},{n,n}],1]

Show[graSierp,Graphics[{FaceForm[],EdgeForm[Red],blocks[7]}]]

enter image description here

Of course number of partitions grows as a square for 2D case

Length /@ blocks /@ Range[9]

{1, 4, 9, 16, 25, 36, 49, 64, 81}

Function counting partitions that have any points in them

blockCount[pts_, n_] := Length[Select[blocks[n], MemberQ[RegionMember[#, pts], True] &]]

Accumulating data of partition count for different partition sizes

logMes = ParallelTable[Log@{k, blockCount[ptsSierp, k]}, {k, 20}];

Fitting the log-log scale of the data linearly with the slope measuring fractal dimension

fit[x] = Fit[logMes, {1, x}, x]

0.0884774 + 1.70962 x

which deviates a bit from ideal due to probably random inexact nature of IFS system

N[Log[3]/Log[2]]

1.58496

Plot[fit[x], {x, 0, 3.5}, Epilog -> {Red, PointSize[.02], Point[logMes]}]

enter image description here

Missing features

The following features could be added in future:

  • Offset parameter for overlapping or gapped partitions

  • Real (non-integer) number of partitions

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard
Be respectful. Review our Community Guidelines to understand your role and responsibilities. Community Terms of Use