In the User Guide
vignette it is shown that there is are homeomorphisms An ⟷ ∂Zn ⟷ S2n where An
is the space of n or fewer pairwise
disjoint arcs in the circle, and Zn is the polar zonoid in R2n+1. The forward direction
∂Zn → S2n is the trivial projection onto the unit sphere
centered at (0,...0,π). But the
reverse direction requires intersecting a ray with ∂Zn, which is non-trivial. The
function in the package that performs this intersection is
boundaryfromsphere()
. It expresses ∂Zn as the level set of a
real-valued function, and uses uniroot()
to solve for the
intersection point.
In this vignette, we outline how ∂Zn is defined parametrically and how the real-valued function is derived. This process is called implicitization, see [1]. In the current version of the package, the implicitization has only been computed for n=1,2, and 3.
Throughout this vignette we think of ∂Zn⊆R2n+1 and identify the latter with points (z1,...,zn,L) where zi are complex numbers and L is real.
Assume first that n=1 so there is a single arc in the circle, i.e. a point in A1. We parameterize the arc by its first and last endpoints u1 and v1, both on the unit circle in the complex plane, and proceeding counterclockwise from u1 to v1. Let the length of the arc be l1, so that v1=u1eil1. It is not hard to show that the map A1→∂Z1 is given by (u1,v1)↦( (v1−u1)/i, l1 ) = (z1,L) where z1:=(v1−u1)/i. Similarly, when n=2, it is easy to show that the map A2→∂Z2 is given by: (u1,v1,u2,v2)↦( (v1−u1+v2−u2)/i, (v21−u21+v22−u22)/(2i), l1+l2 ) = (z1,z2,L) and so on for n≥3. Since ui and vi are unit vectors, ui¯ui=1 and vi¯vi=1 where the overline denotes complex conjugate. It follows easily that: ¯z1=(u2v2(v1−u1)+u1v1(v2−u2))(−i/(u1u2v1v2))¯z2=(u22v22(v21−u21)+u21v21(v22−u22))(−i/(2u21u22v21v22))
And using Euler’s formula, one can show: sin(L/2)=v1v2−u1u22i e−iL/2u1u2cos(L/2)=v1v2+u1u22 e−iL/2u1u2
The expressions for n=1 and n=3 are similar. These right-hand-sides are “rational enough” that algebraic geometry can be used for implicitization. We use the Rational Implicitization algorithm in Chapter 3, Section 3 of [1]. The fact that second term in each RHS is a unit complex number plays a simplifying role. The results are in the next section.
Throughout this section we assume that L∈[0,2π]. With lots of help from Macaulay2 [2], followed by manual rearrangement, one can
show that for n = 1,2, and 3 that
(z1,...,zn,L)∈∂Zn iff |γn(z1,...,zn,L)|=ρn(z1,...,zn,L) and (z1,...,zn,L)∈Zn iff |γn(z1,...,zn,L)|≤ρn(z1,...,zn,L) where γn() is a complex-valued function,
and ρn() is a real-valued
function. The details of this are complicated, especially for n=3, and are omitted. For n=4, Macaulay2 runs out of memory and
cannot finish; but I conjecture that these two functions exist for all
n. For small n, they are given in this table:
The functions ρ1() and ρ2() are obviously real, and ρ3() is real because ¯z12z2+z21¯z2 is real.
The case n=1 is in R3 and easy to visualize: (z1,L)∈∂Z1 iff |z1|=2sin(L/2) This is a surface of revolution - a sine wave around the L axis. It is like a football with poles at (0,0) and (0,2π). Note that these 2 poles are exactly the points where the right side of the equality vanishes.
If we define f(z1,...,zn,L):=|γn(z1,...,zn,L)|−ρn(z1,...,zn,L) then f() vanishes on ∂Zn, is negative in the interior
of Zn, and is positive outside
Zn. This level-set
function f() is used in
boundaryfromsphere()
to compute the intersection of a ray
based at (0,π) and ∂Zn. The gradient of f() is used in
arcsfromboundary()
; see the next section.
For x=(z1,...,zn,L)∈∂Zn evaluating the function ∂Zn→An requires the outward normal of a supporting hyperplane to ∂Zn at x. The coordinates of this normal become the coefficients of a trigonometric polynomial, whose roots are the endpoints of arcs. If ∂Zn is smooth at x the supporting hyperplane is unique, and is in fact the gradient of the level-set function f() at x. Also in this case the trigonometric polynomial has the full set of 2n roots, defining n arcs.
But unfortunately, ∂Zn is NOT smooth at all x. We saw this already with n=1, where the surface is not smooth at the 2 poles. At the poles, there are infinitely many supporting planes, the trigonometric polynomial has 0 roots, the “south pole” maps to the empty arc, and the “north pole” to the full circle.
The function ∂Zn→An is implemented in arcsfromboundary()
. This
R function has to deal with the non-smooth case. It
turns out that ∂Zn is
smooth at x iff ρn(x)>0. We saw this already
with n=1. So starting at k=1 and incrementing up to n, it tests ρk(z1,...,zk,L). If ρk(z1,...,zk,L)<ϵ, it
returns a collection of k−1 arcs
in An. Otherwise the surface is
smooth at x and it returns n arcs. Recall that An is the space of n or fewer arcs.
arcsfromboundary()
first calculates the outward pointing
normal at p. The the gradient of the level-set function f() is used to compute this normal; the
expressions for the gradient are more complicated than the ones in the
above table, and are omitted here. This coordinates of this normal are
the coefficients of a trigonometric polynomial whose roots are
calculated with trigpolyroot()
. These roots are the
endpoints of the arcs.
NOTE: The differences Xi:=∂Zi−∂Zi−1 almost surely form a Thom-Mather stratification of ∂Zn⊂R2n+1, but I have not checked this. The conditions for such a stratification are complex, and are in [3]. Each Xi is the image of exactly i arcs. I think that the above functions ρi(), after restriction to Xi, can serve as the distance functions in the stratification.
The forward functions: An ⟶ ∂Zn ⟶ S2n are straightforward. In the package, they are
implemented as boundaryfromarcs()
and
spherefromboundary()
respectively.
But the inverse functions: An ⟵ ∂Zn ⟵ S2n use convergent numerical iteration. The first
one, boundaryfromsphere()
, uses the implicit function
defined above, and this version of the package requires that n = 1, 2, or 3. The second one,
arcsfromsphere()
, solves for the roots of a trigonometric
polynomial and uses base::polyroot()
.
R version 4.5.0 (2025-04-11 ucrt) Platform: x86_64-w64-mingw32/x64 Running under: Windows 11 x64 (build 26100) Matrix products: default LAPACK version 3.12.1 locale: [1] LC_COLLATE=C [2] LC_CTYPE=English_United States.utf8 [3] LC_MONETARY=English_United States.utf8 [4] LC_NUMERIC=C [5] LC_TIME=English_United States.utf8 time zone: America/Los_Angeles tzcode source: internal attached base packages: [1] stats graphics grDevices utils datasets methods base other attached packages: [1] flextable_0.9.7 polarzonoid_0.1-2 loaded via a namespace (and not attached): [1] zip_2.3.3 cli_3.6.5 knitr_1.50 [4] rlang_1.1.6 xfun_0.52 textshaping_1.0.1 [7] gdtools_0.4.2 jsonlite_2.0.0 data.table_1.17.2 [10] glue_1.8.0 xslt_1.5.1 openssl_2.3.2 [13] askpass_1.2.1 V8_6.0.3 htmltools_0.5.8.1 [16] ragg_1.4.0 sass_0.4.10 fontquiver_0.2.1 [19] rmarkdown_2.29 grid_4.5.0 evaluate_1.0.3 [22] jquerylib_0.1.4 fastmap_1.2.0 yaml_2.3.10 [25] lifecycle_1.0.4 compiler_4.5.0 officer_0.6.8 [28] fontLiberation_0.1.0 Rcpp_1.0.14 katex_1.5.0 [31] systemfonts_1.2.3 digest_0.6.37 R6_2.6.1 [34] curl_6.2.2 bslib_0.9.0 logger_0.4.0 [37] uuid_1.2-1 fontBitstreamVera_0.1.1 tools_4.5.0 [40] equatags_0.2.1 xml2_1.3.8 cachem_1.1.0