# Spherical Cap in Julia

I need to use a set of points from a spherical cap to apply KPCA in Julia, but I don’t know how to create these caps, which idea should I use for this application?

If you are interested in sampling from the uniform distribution on the spherical cap then proceed as follows: Consider the unit sphere of parametric equations
x=cos(θ)sin(ϕ)
y=sin(θ)sin(ϕ)
z=cos(ϕ)
ϕ∈[0, π], θ∈[0, 2π], and the sphere cap corresponding to ϕ ∈[0, a].

The function f(ϕ, θ)= sin(ϕ)/4π is the pdf of the uniform distribution on the unit sphere.
It is derived taking into account that the area element on this sphere is
dσ=sin(ϕ)dϕdθ, and the sphere area is 4π.
The marginal densities are g(ϕ)=sin(ϕ)/2, and h(θ)=1/2π, i.e. the two rv, ϕ and θ, are independent, and θ is uniform distributed on [0,2π].
The cummulative distribution function for ϕ is G(ϕ)=(1-cos(ϕ))/2, and its inverse
G^(-1)(u)=acos(1-2u).
Hence for sampling from the uniform distribution on the sphere cap we proceed as follows:

n= 400
a = 40*π/180 #sphere cap corresponding to ϕ in [0, a]
u = 0.5* (1-cos(a))*rand(n)  #sampling from unif distr. on [0, (1-cos(a)/2))
ϕ = acos.(1 .- 2*u) #inverse transform sampling
θ = 2π*rand(n) #uniform sampling
x = cos.(θ) .* sin.(ϕ)
y = sin.(θ) .* sin.(ϕ)
z=  cos.(ϕ);


4 Likes

Thank you for your support, I was not able to visualize the idea to be used. It would be too much to ask you to provide the code that generated this graphic, when making a surface, it is not very nice to visualize.

This is the code for the cap plot:

using PlotlyJS

R = 1
a = 40*π/180  # consider the sphere cap for
N= 100
θ = collect(LinRange(0, 2π, N))
ϕ = collect(LinRange(0, a,  N))
xs = R*cos.(θ)*sin.(ϕ)'
ys = R*sin.(θ)*sin.(ϕ)'
zs = ones(N)*cos.(ϕ)';
n= 400
R=1.01
u = 0.5* (1-cos(a))*rand(n)
ϕ = acos.(1 .- 2*u)
θ = 2π*rand(n)
x = R*cos.(θ) .* sin.(ϕ)
y = R*sin.(θ) .* sin.(ϕ)
z=  R*cos.(ϕ)
pl = Plot([surface(x=xs, y=ys, z=zs, colorscale= [[0, "#555555"], [1, "#555555"]], showscale=false),
scatter3d(x=x, y=y, z=z, mode="markers", marker_size=3)],
Layout(width=600,  scene_aspectmode="data", scene_camera_eye=attr(x=1.75, y=1.75, z=0.9)))
display(pl)


scene_aspectmode="data" makes the difference and does not let to be displayed a deformed cap.

If you want to use a real colorscale for the spherical cap, not just a single color, replace the plot definition by:

pl = Plot([surface(x=xs, y=ys, z=zs, colorscale= colors.matter, reversescale=true, showscale=false),
scatter3d(x=x, y=y, z=z, mode="markers", marker_size=3, marker_color="black")],
Layout(width=600,  scene_aspectmode="data", scene_camera_eye=attr(x=1.75, y=1.75, z=0.9)))

1 Like