On 21/05/14 23:34, James Thorson wrote:
> Hi all,
>
> In case anyone is following this thread, I thought I'd post a final
> version of the R-code that replicates the computation of M0, M1, and M2
> from R-INLA (i.e., the "inla.spde2.matern" function) given a particular
> triangular mesh. This code *appears* to allow inclusion of the H-matrix
> to estimate geometric anisotropy. However, I still welcome feedback on:
>
> 1. Whether there's some mistake in my interpretation of the H-matrix
For stationary anisotropy, take a look at equation (20) of Appendix A of
the Lindgren et al (2011) JRRSB SPDE/GMRF paper. When the SPDE is
defined as
(\kappa^2 - \nabla \cdot H \nabla) x(s) = W(s)
the matrix in the G-element calculation should be the "adjugate" of H,
in the non-singular case (the only one relevant here) defined as
adj(H) = det(H) H^{-1}
With that modification your code looks correct.
> 2. How the B-matrix from Lindgren et al. (2011) enters into the
> computation (I calculate the B-matrix but it doesn't appear necessary to
> replicate the output from "inla.spde2.matern").
The B-matrix is only used for for special constructions when no using
Neumann conditions, so it's correct that is doesn't and shouldn't affect
the inla.spde2.matern() output in the normal cases.
One important note on your code however is that you're not using sparse
matrices; while it's possible to convert non-sparse storage into sparse,
you still use a lot more memory while building the matrices than is
necessary. It's much more efficient to first build index-value triplets
(i,j,value), and build the sparse matrix using sparseMatrix()
as a post-processing step. This will also automatically accumulate the
values for duplicated elements, so no special code for that is needed.
I've attached Matlab code that uses this approach; the syntax is very
similar to what one would need in R; the Matlab sparse() function does
exactly the same thing as R's sparseMatrix() from the Matrix package.
Also note that the internal storage in spde$param.inla might change, so
for a safer comparison of the matrices, compare with the output from
inla.fem(mesh, order=2)
instead, as that is the more direct interface to the C++-code used
internally by R-INLA.
Experimental non-stationary anisotropic code is in the fmesher program:
https://code.google.com/p/inla/source/browse/fmesher/src/mesh.cc#2370
and can be accessed through the internal "smorgasbord" function:
gamma = c(...) ## length n vector of baseline diffusion
vec = matrix(...) ## n-by-3 matrix of anisotropy vectors
smorg = (INLA:::inla.fmesher.smorg(mesh.globe$loc, mesh.globe$graph$tv,
fem=2,
aniso=list(gamma,vec),
output=c("g1aniso","g2aniso")))
g1 = smorg$g1aniso
g2 = smorg$g2aniso
In the stationary case, gamma should be rep(something, mesh$n)
and vec should have mesh$n equal rows, with third column equal to zero
(for planar meshes; on the sphere they should be tangential).
Finn L