From b0ae0361d92a37387d52fc6f0fe8f6aacafba7eb Mon Sep 17 00:00:00 2001 From: Raimon Tolosana-Delgado <tolosa53@fwg206.ad.fz-rossendorf.de> Date: Thu, 1 Oct 2020 14:10:51 +0200 Subject: [PATCH] C code doubled omp vs NOomp; extension of turning bands 2D to function as 3D (necessary for spherical models) --- DESCRIPTION | 2 +- R/geostats.R | 40 ++++++++++++++++++- src/gmGeostats.c | 101 ++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 135 insertions(+), 8 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 075e0b9..b0343f8 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -53,7 +53,7 @@ License: CC BY-SA 4.0 | GPL (>=2) URL: https://gitlab.hzdr.de/geomet/gmGeostats Copyright: (C) 2020 by Helmholtz-Zentrum Dresden-Rossendorf and Edith Cowan University; gsi.DS code by Hassan Talebi -RoxygenNote: 7.1.0 +RoxygenNote: 7.1.1 Roxygen: list(markdown = TRUE) Encoding: UTF-8 VignetteBuilder: knitr diff --git a/R/geostats.R b/R/geostats.R index 8e1ae85..45d1e54 100644 --- a/R/geostats.R +++ b/R/geostats.R @@ -89,6 +89,7 @@ gsi.calcCgram <- function(X,Y,vgram,ijEqual=FALSE) { #' and nvar = nr of variables in vgram #' @useDynLib gmGeostats CMVTurningBands gsi.TurningBands <- function(X,vgram,nBands,nsim=NULL) { + # checks and preps stopifnot(length(as.integer(nBands))==1) d <- dim(vgram$nugget)[1] m <- ncol(X) @@ -96,6 +97,23 @@ gsi.TurningBands <- function(X,vgram,nBands,nsim=NULL) { stopifnot( all(dim(vgram$nugget)==c(d,d))) stopifnot( all(dim(vgram$sill)==c(k,d,d))) stopifnot( all(dim(vgram$M)==c(k,m,m))) + # extend to 3D if 2D + m0 = 3 + if(m<3){ + m0 = m + X = cbind(X, 0, 0) + paveId = function(i){ + M = diag(3) + M[1:m, 1:m] = vgram$M[i,,] + return(M) + } + M = sapply(1:k, paveId) + dim(M) = c(3,3,k) + M = aperm(M, c(1,2,3)) + vgram$M = M + m = 3 + } + # run! if( is.null(nsim) ) { erg<-.C("CMVTurningBands", dimX=checkInt(dim(X),2), @@ -111,7 +129,8 @@ gsi.TurningBands <- function(X,vgram,nBands,nsim=NULL) { moreCgramData=checkDouble(vgram$data,k), PACKAGE = "gmGeostats" ) - cbind(X,Z=t(structure(erg$Z,dim=c(d,nrow(X))))) + erg = cbind(X[, 1:m0],Z=t(structure(erg$Z,dim=c(d,nrow(X))))) + return(erg) } else { nsim <- checkInt(nsim,1) stopifnot(nsim>0) @@ -129,7 +148,8 @@ gsi.TurningBands <- function(X,vgram,nBands,nsim=NULL) { moreCgramData=checkDouble(vgram$data,k), PACKAGE = "gmGeostats" ) - aperm(structure(erg$Z,dim=c(d,nrow(X),nsim)),c(2,1,3)) + erg = aperm(structure(erg$Z,dim=c(d,nrow(X),nsim)),c(2,1,3)) + return(erg) } } @@ -171,6 +191,22 @@ gsi.CondTurningBands <- function(Xout, Xin, Zin, vgram, normal<-FALSE } nsim <- checkInt(nsim,1) + # extend to 3D if 2D + m0 = 3 + if(m<3){ + m0 = m + X = cbind(X, 0, 0) + paveId = function(i){ + M = diag(3) + M[1:m, 1:m] = vgram$M[i,,] + return(M) + } + M = sapply(1:k, paveId) + dim(M) = c(3,3,k) + M = aperm(M, c(1,2,3)) + vgram$M = M + m = 3 + } erg <- .C("CCondSim", dimZin=checkInt(dimZin,2), Zin =checkDouble(Zin), diff --git a/src/gmGeostats.c b/src/gmGeostats.c index 1690f98..58d8e05 100644 --- a/src/gmGeostats.c +++ b/src/gmGeostats.c @@ -421,6 +421,7 @@ void CMVTurningBands( (*bandSim[typeCgram[ss]])(n,projs,band,1.0,moreCgramData+ss); /* this function takes the projs and returns on band the the curve */ /* ... multiply the eigenvector by the curve, and accumulate */ +#ifdef _OPENMP #pragma omp parallel for \ if(!omp_in_parallel()&&0) \ num_threads(omp_get_num_procs()) \ @@ -431,6 +432,14 @@ void CMVTurningBands( Z[d*i+j]+=d2; } } +#else + for(i=0;i<n;i++){ /* location */ + for(j=0;j<d;j++){ /* variable */ + d2 = sqrtSill[ss + *nCgrams *(j+d*ev)]*band[i]; + Z[d*i+j]+=d2; + } + } +#endif } } } @@ -521,6 +530,7 @@ void CCondSim( Rprintf("starting conditioning by dual kriging\n"); /* Kriging from simulated using Cinv */ // Create differenes of obs and sim +#ifdef _OPENMP #pragma omp parallel \ if(!omp_in_parallel()) \ num_threads(omp_get_num_procs()) \ @@ -536,6 +546,16 @@ void CCondSim( } } } +#else + for(int sim=0;sim<nsim;sim++) { + int shift=nd*sim; + for(int i=0;i<nin;i++) + for(int j=0;j<d;j++){ + int k=d*i+j; + Z[k+shift]-=Zin[k]; + } + } +#endif /* Z[hinten] -= \hat{Z[hinten]}(Z[vorn]) = cov(hinten,vorn)%*% Cinv %*% Z[vorn] */ /* dbuf = Cinv %*% Z[vorn] Cinv in R ^ d*nin x d*nin @@ -543,6 +563,7 @@ void CCondSim( */ // Dual Kriging preparation +#ifdef _OPENMP #pragma omp parallel for \ if(!omp_in_parallel()&&0) \ num_threads(omp_get_num_procs()) \ @@ -560,6 +581,21 @@ void CCondSim( dbuf+dmnin*sim, &oneI); } +#else + for(sim=0;sim<nsim;sim++) { + F77_NAME(dgemv)(&No, + &dmnin, + &dmnin, + &one, + Cinv, + &dmnin, + Z+nd*sim, + &oneI, + &zero, + dbuf+dmnin*sim, + &oneI); + } +#endif // /* points in*/ //for(i=0;i<nin;i++) //for(j=0;j<m;j++) @@ -606,6 +642,7 @@ void CCondSim( //} /* Z[,i] += t(cbuf(d*nin,d)) %*% dbuf(d*nin) */ +#ifdef _OPENMP #pragma omp parallel for \ if(!omp_in_parallel()&&0) \ num_threads(omp_get_num_procs()) \ @@ -623,7 +660,21 @@ void CCondSim( Z+i*d+nd*sim, &oneI); } - +#else + for(sim=0;sim<nsim;sim++) { + F77_NAME(dgemv)(&Transposed, + &dmnin, + &d, + &minus1, + cbuf, + &dmnin, + dbuf+dmnin*sim, + &oneI, + &one, + Z+i*d+nd*sim, + &oneI); + } +#endif } } @@ -693,7 +744,8 @@ extern void anaForwardC(const int *dimX, const double h=((double)1.0)/steps; if( dimY[0]!=m ) error("anaForwardC: x and y have different number of variables / rows"); -#pragma omp parallel for +#ifdef _OPENMP + #pragma omp parallel for for(size_t i=0;i<nx;i++) { double v1[m]; double v2[m]; @@ -712,9 +764,29 @@ extern void anaForwardC(const int *dimX, mx[j]+=0.5*h*(v1[j]+v2[j]); } } - +#else + for(size_t i=0;i<nx;i++) { + double v1[m]; + double v2[m]; + double xx[m]; + double *mx=x+m*i; + for(size_t s=0;s<steps;s++) { + // v1 + anaV(v1,m,mx,s*h,dimY,y,wY,sigma0,sigma1); + // xx=x+h*v1 + for(int j=0;j<m;j++) + xx[j]=mx[j]+h*v1[j]; + // v2 + anaV(v2,m,xx,(s+1)*h,dimY,y,wY,sigma0,sigma1); + // x+=0.5*h*(v1+v2) + for(int j=0;j<m;j++) + mx[j]+=0.5*h*(v1[j]+v2[j]); + } + } +#endif } + static R_NativePrimitiveArgType anaBackwardC_t[] = { /* INTSXP,REALSXP */ /* dimX, x, dimY y wY stepsp sigma0p sigma1p */ INTSXP,REALSXP,INTSXP,REALSXP,REALSXP,INTSXP, REALSXP, REALSXP @@ -739,6 +811,7 @@ extern void anaBackwardC(const int *dimX, const double h=((double)1.0)/steps; if( dimY[0]!=m ) error("anaBackwardC: x and y have different number of variables / rows"); +#ifdef _OPENMP #pragma omp parallel for for(size_t i=0;i<nx;i++) { double v1[m]; @@ -757,9 +830,27 @@ extern void anaBackwardC(const int *dimX, for(int j=0;j<m;j++) mx[j]-=0.5*h*(v1[j]+v2[j]); } - } - +#else + for(size_t i=0;i<nx;i++) { + double v1[m]; + double v2[m]; + double xx[m]; + double *mx=x+m*i; + for(size_t s=0;s<steps;s++) { + // v1 + anaV(v1,m,mx,1-s*h,dimY,y,wY,sigma0,sigma1); + // xx=x-h*v1 + for(int j=0;j<m;j++) + xx[j]=mx[j]-h*v1[j]; + // v2 + anaV(v2,m,xx,1-(s+1)*h,dimY,y,wY,sigma0,sigma1); + // x+=0.5*h*(v1+v2) + for(int j=0;j<m;j++) + mx[j]-=0.5*h*(v1[j]+v2[j]); + } + } +#endif } -- GitLab