Function Repository Resource:

OrderConvexClosure

Source Notebook

Compute the smallest order-convex superset of a subset within a parent totally ordered set

Contributed by: E. Chan-López, A. Martín-Ruiz & Carlos Antonio Marín Mendoza

ResourceFunction["OrderConvexClosure"][subset,parentSet]

returns the smallest order-convex subset of parentSet containing subset, consisting of all elements of parentSet lying in Interval[MinMax[subset]].

Details and Options

ResourceFunction["OrderConvexClosure"][subset,parentSet] computes the order-convex closure i.e. all elements of parentSet lying between the minimum and maximum elements of subset under the specified ordering.
Both subset and parentSet must be lists whose elements support ordering via LessEqual or specified "ComparisonFunction".
The option "ComparisonFunction" specifies the ordering used to determine convexity. The default is LessEqual.
When using the default comparison:
Numericuse optimized Min/Max evaluation
Non-numericfall back to canonical Order (e.g. strings, symbols)
The interval defining the closure is computed using the specified ordering (via "ComparisonFunction"). The output, however, preserves the original ordering of elements as they appear in parentSet. This separates the structural notion of order (used to define convexity) from the presentation order of the data.
The result consists of all elements of parentSet lying in Interval[MinMax[subset]] with respect to the chosen ordering.
ResourceFunction["OrderConvexClosure"][{},parentSet] returns {}.
The operator is idempotent: applying it multiple times yields the same result as applying it once.
The operator is extensive, meaning that the original subset is always contained in its closure: In particular, no elements from subset are removed.

Examples

Basic Examples (4) 

The closure fills in missing elements within the range:

In[1]:=
ResourceFunction["OrderConvexClosure"][{2, 3, 5}, Range[10]]
Out[1]=

A convex set is a fixed point. It returns itself:

In[2]:=
ResourceFunction["OrderConvexClosure"][{3, 4, 5}, Range[10]]
Out[2]=

The closure of a singleton is the singleton itself:

In[3]:=
ResourceFunction["OrderConvexClosure"][{7}, Range[10]]
Out[3]=

Applied to a non-contiguous parent set:

In[4]:=
ResourceFunction[
 "OrderConvexClosure"][{10, 40}, {5, 10, 20, 30, 40, 50}]
Out[4]=

Scope (3) 

Works with rational elements:

In[5]:=
ResourceFunction[
 "OrderConvexClosure"][{1/3, 2/3}, {0, 1/3, 1/2, 2/3, 1}]
Out[5]=

Works with strings under lexicographic order:

In[6]:=
ResourceFunction[
 "OrderConvexClosure"][{"b", "d"}, {"a", "b", "c", "d", "e"}]
Out[6]=

Works with symbolic heads that have a canonical ordering:

In[7]:=
ResourceFunction["OrderConvexClosure"][{b, e}, {a, b, c, d, e, f}]
Out[7]=

Options (3) 

The default value of "ComparisonFunction" is LessEqual:

In[8]:=
Options[
ResourceFunction["OrderConvexClosure"]]
Out[8]=

Use GreaterEqual to compute the closure under the reverse order:

In[9]:=
ResourceFunction["OrderConvexClosure"][{8, 3}, Range[10], "ComparisonFunction" -> GreaterEqual]
Out[9]=

A custom comparison function. Closure under order by string length:

In[10]:=
ResourceFunction["OrderConvexClosure"][{"ab", "abcde"},
 	{"a", "ab", "xyz", "test", "abcde", "longer"},
 	"ComparisonFunction" -> Function[LessEqual[StringLength[#], StringLength @ #2]]
 ]
Out[10]=

Applications (3) 

Find intermediate stations between two stops on a Mexico City Metro line, using positional ordering rather than alphabetical order via a custom index-based comparison:

In[11]:=
With[
 	{
  		line = {
    			"Observatorio", "Tacubaya", "Juanacatlán", "Chapultepec", "Sevilla", "Insurgentes",
    			"Cuauhtémoc", "Balderas", "Salto del Agua", "Isabel la Católica", "Pino Suárez",
    			"Merced", "Candelaria", "San Lázaro", "Moctezuma", "Balbuena", "Blvd. Puerto Aéreo",
    			"Gómez Farías", "Zaragoza", "Pantitlán"
    		}
  	},
 	With[{pos = AssociationThread[line, Range @ Length @ line]},
  		ResourceFunction["OrderConvexClosure"][{"Chapultepec", "Balderas"},
   			line,
   			"ComparisonFunction" -> Function[LessEqual[pos[#], pos @ #2]]
   		]
  	]
 ]
Out[11]=

Determine the contiguous range of monthly periods between two known events in a fiscal calendar:

In[12]:=
With[
 	{
  		cal = DateRange[DateObject @ {2026, 1, 1},
    			DateObject @ {2026, 12, 31},
    			"Month"
    		]
  	},
 	ResourceFunction["OrderConvexClosure"][
  		{DateObject @ {2026, 3, 1}, DateObject @ {2026, 7, 1}},
  		cal
  	]
 ]
Out[12]=

The function reconstructs the full sequence of monthly periods between the two given dates, ensuring interval completeness within the fiscal calendar.


Extract all rows in a dataset whose key falls between two boundary values:

In[13]:=
With[{keys = {100, 200, 300, 400, 500, 600}},
 	ResourceFunction["OrderConvexClosure"][{200, 500}, keys]
 ]
Out[13]=

Properties and Relations (6) 

Idempotence. Applying the closure twice yields the same result:

In[14]:=
With[{s = {1, 5, 9}, p = Range @ 10},
 	SameQ[ResourceFunction["OrderConvexClosure"][
   ResourceFunction["OrderConvexClosure"][s, p], p],
  		ResourceFunction["OrderConvexClosure"][s, p]
  	]
 ]
Out[14]=

A subset is convex if and only if it equals its closure:

In[15]:=
With[{s = {3, 4, 5}, p = Range @ 10},
 	SameQ[Sort @ s, ResourceFunction["OrderConvexClosure"][s, p]]
 ]
Out[15]=

The closure equals the subset joined with its defect (disjoint union):

In[16]:=
With[{s = {1, 3, 7}, p = Range @ 10},
 	SameQ[Sort @ ResourceFunction["OrderConvexClosure"][s, p],
  		Sort @ Join[s, Complement[ResourceFunction["OrderConvexClosure"][s, p], s]]
  	]
 ]
Out[16]=

The result of OrderConvexClosure always satisfies OrderConvexQ:

In[17]:=
With[{s = {2, 5, 8}, p = Range @ 10},
 	ResourceFunction["OrderConvexQ"][
  ResourceFunction["OrderConvexClosure"][s, p], p]
 ]
Out[17]=

Extensiveness. The closure contains the original subset:

In[18]:=
With[{s = {2, 7, 9}, p = Range @ 10},
 	SubsetQ[ResourceFunction["OrderConvexClosure"][s, p], s]
 ]
Out[18]=

Monotonicity. If , then :

In[19]:=
With[
 	{
  		p = Range @ 20,
  		a = {3, 7},
  		b = {1, 3, 7, 12}
  	},
 	SubsetQ[ResourceFunction["OrderConvexClosure"][b, p], ResourceFunction["OrderConvexClosure"][a, p]]
 ]
Out[19]=

Possible Issues (1) 

OrderConvexClosure does not verify . If subset contains elements absent from parentSet, the closure is computed based on the range of subset but filtered from parentSet only. The function is designed for total orders only. For partial orders, the interval characterization does not hold. When using a custom "ComparisonFunction", the function must be a valid total preorder: reflexive, transitive, and total. Passing a non-transitive relation yields undefined behaviour. If subset has elements not in parent set, they act as bounds but do not appear in the output:

In[20]:=
ResourceFunction["OrderConvexClosure"][{2, 8}, {1, 3, 5, 7, 9}]
Out[20]=

Neat Examples (4) 

Visualize the closure on a number line. Red points show the original subset. Green marks the convex closure:

In[21]:=
With[{s = {2, 5, 9}, p = Range @ 12},
 	NumberLinePlot[{p, ResourceFunction["OrderConvexClosure"][s, p], s},
  		PlotStyle -> {Gray, Darker[Green], Red},
  		PlotLegends -> {"Parent Set", "Convex Closure", "Subset"},
  		Spacings -> 0.5
  	]
 ]
Out[21]=

Enumerate all distinct closures obtainable from 2-element subsets of {1,,8}:

In[22]:=
Length[
 	DeleteDuplicates[
  		Map[ResourceFunction["OrderConvexClosure"][#, Range[8]] &, Subsets[Range @ 8, {2}]]
  	]
 ]
Out[22]=

Fractal structure of the logistic map attractor. Discretize the orbit at r = 3.82 on a grid of resolution 0.001. Compare the orbit with its convex closure. The difference is the convex defect. Its size reflects gaps in the Cantor-like attractor:

In[23]:=
With[{r = 3.82, res = 0.001},
 	Module[{grid, orbit, disc, closure, defect},
  		grid = Range[0., 1., res];
  		orbit = NestList[Function[r * # * (1 - #)], 0.1, 10000];
  		disc = DeleteDuplicates @ Round[orbit, res];
  		closure = ResourceFunction["OrderConvexClosure"][disc, grid];
  		defect = Complement[closure, disc];
  		Show[
   			NumberLinePlot[{closure, defect},
    				PlotStyle -> {{Darker[Green], PointSize @ 0.0125}, {Red, PointSize @ 0.0125}},
    				PlotLegends -> {"Convex Closure", "Defect gaps"}
    			],
   			PlotLabel -> Row[
     				{
      					"Orbit: ", Length[disc], "  Closure: ", Length @ closure, "  Defect: ",
      					Length @ defect
      				}
     			]
   		]
  	]
 ]
Out[23]=

Sweep the parameter r from 3.5 to 4.0 and plot the size of the convex closure relative to the discretised orbit. As approaches 4, the attractor fills the interval and the ratio tends to 1:

In[24]:=
ListLinePlot[
 	Table[
  		Module[{grid, orbit, disc, closure},
   			grid = Range[0., 1., 0.001];
   			orbit = NestList[Function[r * # * (1 - #)], 0.1, 5000];
   			disc = DeleteDuplicates @ Round[orbit, 0.001];
   			closure = ResourceFunction["OrderConvexClosure"][disc, grid];
   			{r, N[Length[disc] / Length[closure]]}
   		],
  		{r, 3.5, 4., 0.01}
  	],
 	AxesLabel -> {"r", "|orbit|/|closure|"},
 	PlotLabel -> "Orbit Density Within Convex Hull", Filling -> Bottom
 ]
Out[24]=

Publisher

Ramón Eduardo Chan López

Version History

  • 1.0.0 – 01 April 2026

Source Metadata

Related Resources

Author Notes

OrderConvexClosure constructs the order-convex closure of a subset within a finite totally ordered set. The ambient order is determined by parent set, whose elements are assumed to support comparison via LessEqual. The function returns the smallest interval-complete superset of the input subset relative to parent set, corresponding to the convex hull in the induced order. It is particularly useful for restoring contiguous structure in discretized domains, including integer grids and sampled angular coordinates.

License Information