rm(list=ls())
library(RGeostats)
library(rgl)
library(knitr)
knit_hooks$set(webgl = hook_webgl)
variety.define(flag.sphere=TRUE)
##
## Parameters for Variety Definition
## ---------------------------------
## The Spherical Variety is defined
## - Radius of the Sphere = 6371.000000
constant.define("nproc",NA)
This file is meant to demonstrate the procedure used to perform Simulations on the Sphere. This function requires the definition of the change of space; the resulting file corresponds to a regular grid file, where nodes are regularly located along longitude and latitude regular angles. Finally for commodity, the visualization is performed using RGL library.
First we need to create the output grid where the nodes vary along the longitude from 0 to 360 by mesh of 1 degree (hence 361 nodes); and from -90 to +90 degrees in latitude by mesh of 1 degree (hence 181 meshes).
grid = db.create(nx=c(361,181),x0=c(0,90),dx=c(1,1))
For the simulations, we use a Spatial isotropic Model which is defined below:
model = model.create(vartype="cubic",range=0.5)
Some parameters are defined and will be kept constant for all tests (unless overwritten). This is the case in particular for:
nbfdef = 10000
In general, this function enables simulating any covariance model (defined on the Sphere). It requires the preliminary calculation of the covariance spectrum. Two specific constructions have been coded: the spectrum of Chentsov Covariance and the one for Exponential Covariance. In addition any standard 3-D model (defined in the Euclidean space) can be converted into the corresponding Model on the Sphere using the following Yadrenko formula:
\[ C(\alpha) = C_3 \left(2 \sin \frac{\alpha}{2} \right) for \, 0<= \alpha <= \pi \]
In a first step, we will pay attention on the generated spectrum of the covariance. In particular, we make sure that the coefficients of the spectrum are all defined, positive, monotonously decreasing. Moreover the series are truncated if the coefficients are constantly smaller than a given tolerance and as soon as there sum is reasonably close to one. However, their number is limited to a maximum number.
Unless we are using a specific construction mode, the coefficients of the spectrum are calculated as follows. We start with the Schoenberg formula:
\[ C(\alpha) = \sum_{n=0}^{\infty} a_n P_n \left( cos \alpha \right) \]
Using the orthogonality of the \(P_n\) polynomials, we derive:
\[ a_n = \int_{0}^{\pi} C(\alpha) \tilde{P}_n(cos \alpha) sin \alpha \sqrt{\frac{2n+1}{2}} d \alpha \]
set.keypair("Simsph_Shunt",1)
dummy = simsph(grid,model,special=1,verbose=TRUE)
##
## Generation of Covariance spectrum in Spherical Coordinates
## ----------------------------------------------------------
## Using Chentsov construction
## Spectrum Tolerance = 1e-05
## Random generation seed = 232131
## Number of frequencies = 10000
## Number of basic functions = 100
## Cumulated Spectrum = 0.999936
## Sum of negative weights = 0.000000
freqs = get.keypair("Simsph_Spectrum_Frequencies")
plot(freqs, main="Chentsov Covariance Spectrum",
type="l",ylab="Frequency")
plot(freqs, type="b", xlim=c(1,20),
main="Chentsov Covariance Spectrum (zoom)",ylab="Frequency")
set.keypair("Simsph_Shunt",1)
dummy = simsph(grid,model,special=2,verbose=TRUE)
##
## Generation of Covariance spectrum in Spherical Coordinates
## ----------------------------------------------------------
## Using Exponential construction
## Spectrum Tolerance = 1e-05
## Random generation seed = 232131
## Number of frequencies = 10000
## Number of basic functions = 100
## Cumulated Spectrum = 0.999800
## Sum of negative weights = 0.000000
freqs = get.keypair("Simsph_Spectrum_Frequencies")
plot(freqs, main="Exponential Covariance Spectrum",
type="l",ylab="Frequency")
plot(freqs, type="b", xlim=c(1,20),
main="Exponential Covariance Spectrum (zoom)",ylab="Frequency")
set.keypair("Simsph_Shunt",1)
dummy = simsph(grid,model,special=0,verbose=TRUE)
##
## Generation of Covariance spectrum in Spherical Coordinates
## ----------------------------------------------------------
## Number of discretization = 360
## Spectrum Tolerance = 1e-05
## Random generation seed = 232131
## Number of frequencies = 41
## Number of basic functions = 100
## Cumulated Spectrum = 0.999567
## Sum of negative weights = 0.000000
freqs = get.keypair("Simsph_Spectrum_Frequencies")
plot(freqs, main="Standard Model Spectrum",type="l",ylab="Frequency")
plot(freqs, type="b", xlim=c(1,50),
main="Standard Model Spectrum (zoom)",ylab="Frequency")
Then a number of basic functions is generated (their number is equal to the nbf argument). Each basic structure is characterized by:
Given the spectrum, we can check the distribution of all these parameters. We plot the experimental histogram of the generated degree values (in black) and overlay the theoretical discretized spectrum (in red).
This is perform ed using the internal function display.spectrum.degrees.
display.spectrum.degrees <- function(special=0,model,nbf=nbfdef,
dslice=20,title="Undefined")
{
set.keypair("Simsph_Shunt",2)
dummy = simsph(grid,model,special=special,verbose=FALSE,nbf=nbf)
degrees = get.keypair("Simsph_Array_Degree")
freqs = get.keypair("Simsph_Spectrum_Frequencies")
fmax = range(freqs)[2]
dmax = range(degrees)[2]
h.result = hist(degrees,breaks=seq(-0.5,0.5+dmax),plot=FALSE)
nval = length(h.result$mids)
plot(h.result$mids,h.result$density,xlim=c(0,dslice),ylim=c(0,fmax),
type="b",col="black",pch=19,
xlab="Degree N",ylab="Frequency",main=title)
lines(x=h.result$mids,y=freqs[1:nval],add=T,
type="b",col="red",pch=19)
set.keypair("Simsph_Shunt",0)
invisible()
}
The following tests are performed for different models:
display.spectrum.degrees(special=1,model,
title="Chentsov Covariance Spectrum")
display.spectrum.degrees(special=2,model,
title="Exponential Covariance Spectrum")
display.spectrum.degrees(special=0,model,dslice=40,
title="Standard Model Spectrum")
This is perform ed using the internal function display.spectrum.order.
display.spectrum.order <- function(special=0,model,nbf=nbfdef,
title="Undefined")
{
set.keypair("Simsph_Shunt",2)
dummy = simsph(grid,model,special=special,verbose=TRUE,nbf=nbf)
degrees = get.keypair("Simsph_Array_Degree")
orders = get.keypair("Simsph_Array_Order")
freqs = get.keypair("Simsph_Spectrum_Frequencies")
dmax = range(degrees)[2]
fmax = range(freqs)[2]
h.result = hist(orders,breaks=seq(-0.5-dmax,0.5+dmax),plot=FALSE)
nval = floor(length(h.result$mids) / 2) + 1
plot(h.result$mids,h.result$density,xlim=c(-20,20),
type="b",col="black",pch=19,
xlab="Order K",ylab="Frequency",main=title)
set.keypair("Simsph_Shunt",0)
invisible()
}
The following tests are performed for different models:
display.spectrum.order(special=1,model,
title="Chentsov Covariance Spectrum")
##
## Generation of Covariance spectrum in Spherical Coordinates
## ----------------------------------------------------------
## Using Chentsov construction
## Spectrum Tolerance = 1e-05
## Random generation seed = 232131
## Number of frequencies = 10000
## Number of basic functions = 10000
## Cumulated Spectrum = 0.999936
## Sum of negative weights = 0.000000
## Maximum degree = 5747
## Minimum order = -2218
## Maximum order = 2742
display.spectrum.order(special=2,model,
title="Exponential Covariance Spectrum")
##
## Generation of Covariance spectrum in Spherical Coordinates
## ----------------------------------------------------------
## Using Exponential construction
## Spectrum Tolerance = 1e-05
## Random generation seed = 232131
## Number of frequencies = 10000
## Number of basic functions = 10000
## Cumulated Spectrum = 0.999800
## Sum of negative weights = 0.000000
## Maximum degree = 8094
## Minimum order = -3804
## Maximum order = 3862
display.spectrum.order(special=0,model,
title="Standard Model Spectrum")
##
## Generation of Covariance spectrum in Spherical Coordinates
## ----------------------------------------------------------
## Number of discretization = 360
## Spectrum Tolerance = 1e-05
## Random generation seed = 232131
## Number of frequencies = 41
## Number of basic functions = 10000
## Cumulated Spectrum = 0.999567
## Sum of negative weights = 0.000000
## Maximum degree = 40
## Minimum order = -34
## Maximum order = 39
This is perform ed using the internal function display.spectrum.phase.
display.spectrum.phase <- function(special=0,model,nbf=nbfdef,
title="Undefined")
{
set.keypair("Simsph_Shunt",2)
dummy = simsph(grid,model,special=special,verbose=FALSE,nbf=nbf)
phases = get.keypair("Simsph_Array_Phase")
h.result = hist(phases,breaks=100,
main="Histogram of phases",xlab="")
set.keypair("Simsph_Shunt",0)
invisible()
}
The simulation of phase is independent from the type of covariance; therefore only one type is used (i.e. Chentsov covariance). The histogram is build with 100 classes.
display.spectrum.phase(special=1,model,
title="Chentsov Covariance Spectrum")
The simulation of the basic function (rank j) over the sphere is obtained through the following formula:
\[ Z_{j}(\theta,\phi) = 2 \tilde{P}_{N_j,K_j} \left(cos \theta \right) cos \left( K \phi + \psi_j \right) \]
where:
Finally, the outcome of the GRF at any point on the sphere (characterized by its longitude and latitude) is obtained as follows:
\[ Z(\theta, \phi) = \frac {\sum_{j}^{n} Z_j(\theta,\phi)}{\sqrt{n}}\]
In this paragraph, we will check the Legendre Function of various degrees and orders. The result should be represented graphically. Unfortunately, the output according to RGL interface does not allow including the results in a standard PDF or HTML file. Therefore the next chunk should be operated several time, in a trial-and-error manner, with different values for the testing parameters.
a = simsph(grid,model,special=1,flag.test=TRUE,
test.degree=1,test.order=0,test.phase=0)
#plot(a)
In this paragraph, all the plotting activities are commented out at it does not seem to be feasible to hook Rgl library within knitr procedure of Rstudio.
Now that all the elements have been tested, it is time to perform the simulation on sphere. We start with a Cubic Model with a range of 0.5.
model = model.create(vartype="cubic",range=0.5,sill=1)
a = simsph(grid,model,nbf=1000)
#plot(a)
We also use a periodic Model such as the Matern one with a range of 0.03 and a third parameter set to 0.01.
model = model.create(vartype="J-Bessel",range=0.03,param=0.01)
a = simsph(grid,model,nbf=1000)
#plot(a)