/* Authors Martin Schlather, schlather@math.uni-mannheim.de Gneiting's space-time covariance models and related models Copyright (C) 2006 -- 2015 Martin Schlather This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "RF.h" #include "Operator.h" #define AVESTP_MINEIGEN 2 #define AVESTP_LOGDET 3 #define AVESTP_V 4 #define AVESTP_LOGV 5 #define AVESTP_LOGMIXDENS 6 #define TOTALAVESTP (AVESTP_LOGMIXDENS + 1) #define AVE_A 0 #define AVE_Z 1 #define AVE_SPACETIME 2 #define AVE_PHI 0 #define AVE_GAUSS 1 void kappa_ave(int i, cov_model *cov, int *nr, int *nc){ bool spacetime = (bool) (PisNULL(AVE_SPACETIME) || P0INT(AVE_SPACETIME)); int dim = spacetime ? cov->tsdim-1 : cov->tsdim; *nr = (i==AVE_A || i==AVE_Z) ? dim : 1; *nc = (i==AVE_A) ? dim : i < CovList[cov->nr].kappas ? 1 : -1; } void ave(double *h, cov_model *cov, double *v) { // f = uAu +zu; bool spacetime = (bool) (PisNULL(AVE_SPACETIME) || P0INT(AVE_SPACETIME)); cov_model *next = cov->sub[0]; int i,j,k,d, dim = spacetime ? cov->tsdim - 1 : cov->tsdim; double detEplus2B, Ah[AveMaxDim], Eplus2B[AveMaxDim], dummy, hh, *A = P(AVE_A), *z = P(AVE_Z), c = spacetime ? h[cov->tsdim-1] : 0.0; // Sockelwert fuer c hh = 0.0; for (k=d=0; dsub[0]; bool spacetime = (bool) (PisNULL(AVE_SPACETIME) || P0INT(AVE_SPACETIME)); int i, j, err, dim = cov->tsdim, spdim = spacetime ? dim - 1 : dim; double *A = P(AVE_A); char msg[2][4] = {"d", "d-1"}; if (cov->xdimown < 2) SERR("The spatial dimension must be at least 2."); if (dim > AveMaxDim) SERR2("For technical reasons max. dimension for ave is %d. Got %d.", AveMaxDim, dim); if (cov->ncol[AVE_A] != spdim || cov->nrow[AVE_A] != spdim) SERR5("A not %sx%s matrix, but %dx%d (dim=%d)", msg[spacetime], msg[spacetime], cov->ncol[AVE_A], cov->nrow[AVE_A], spdim); if (cov->ncol[AVE_Z] != 1 || cov->nrow[AVE_Z] != spdim) SERR1("z not (%s)-dim vector", msg[spacetime]); for (i=0; ixdimprev != cov->tsdim) // || cov->xdimprev != cov->tsdim) return ERRORDIM; if ((err = CHECK(next, dim, 1, PosDefType, XONLY, ISOTROPIC, SCALAR, cov->role // ROLE_COV changed 20.7.14 wg spectral )) != NOERROR) return err; next->delflag = DEL_COV; // set gatternr=nr, since non-negativity ensured if (!isNormalMixture(next->monotone)) return ERRORNORMALMIXTURE; if (CovList[next->nr].spectral == NULL) return ERRORSPECTRAL; // nicht gatter // updatepref(cov, next); ## gute idee? if (next->pref[SpectralTBM] == PREF_NONE) cov->pref[RandomCoin] = cov->pref[Average] = PREF_NONE; // kein setbackward?? // no setbackard return NOERROR; } void rangeave(cov_model VARIABLE_IS_NOT_USED *cov, range_type* ra){ int i; for (i=0; i<=1; i++) { ra->min[i] = RF_NEGINF; ra->max[i] = RF_INF; ra->pmin[i] = -10.0; ra->pmax[i] = 10.0; ra->openmin[i] = true; ra->openmax[i] = true; } ra->min[2] = 0; ra->max[2] = 1; ra->pmin[2] = 0; ra->pmax[2] = 1; ra->openmin[2] = false; ra->openmax[2] = false; } void sd_avestp(cov_model *cov, gen_storage VARIABLE_IS_NOT_USED *S, int dim, double *sd){ ///// window_info *w = &(S->window); int d; double b, alphamin, x2, InvSqrt2a, EmA, *q = cov->q; // see article/GEOSTATS/simuspacetime/simuspacetime2008/simuspacetime.tex // for the reasoning of these calculations BUG; assert(cov->role == Average); q[AVESTP_LOGV] = log(q[AVESTP_V]); for (x2=0.0, d=0; dmax[d] - w->min[d]; x2 += lensimu * lensimu; } // x2 *= 0.25; b = 3.0 * q[AVESTP_V] * x2 / dim; alphamin = (4.0 + 4.0 * b - 2.0 * sqrt(4.0 * b * b + 8.0 * b + 1.0)) / 3.0; InvSqrt2a = 1.0 / sqrt(2.0 * alphamin * 6.0 * q[AVESTP_V]); *sd = InvSqrt2a; EmA = 1.0 - alphamin; cov->mpp.maxheights[0] = exp(-0.5 * log(EmA) - 0.25 * log(alphamin) + b / EmA - 2 * x2); // proportional zum dritten Moment ! /* double radius = sqrt((-9 // so e^{-9} as threshold - 0.25 * dim * (q[AVESTP_LOGV] - 1.14473) // log pi - 0.25 * q[AVESTP_LOGDET] //+ 0.5 * cov_a->logdens - q[AVESTP_LOGMIXDENS] ) / ( - q[AVESTP_MINEIGEN] * q[AVESTP_V]) ); // ??? assert(radius > 0); */ } int structAve(cov_model *cov, cov_model **newmodel) { cov_model *shape, *gaussmix; int err; ASSERT_NEWMODEL_NOT_NULL; if (cov->role != Average) ILLEGAL_ROLE; if ((err = covCpy(newmodel, cov)) != NOERROR) return err; shape = *newmodel; shape->nr = SHAPEAVE; addModel(shape, AVE_GAUSS, GAUSS); gaussmix = shape->sub[AVE_GAUSS]; gaussmix->tsdim = 1; gaussmix->role = ROLE_GAUSS; gaussmix->method = SpectralTBM; return NOERROR; } void logshapeave(double *x, cov_model *cov, double *v, double *Sign) { // nur stationaer bool spacetime = (bool) (PisNULL(AVE_SPACETIME) || P0INT(AVE_SPACETIME)); int d, j, k, dim = spacetime ? cov->tsdim - 1 : cov->tsdim; double f, dummy, r2, *A = P(AVE_A), *z = P(AVE_Z), t = spacetime ? x[cov->tsdim-1] : 0.0, *q = cov->q; f = r2 = 0.0; for (k=d=0; dnr].logmixdens(x, q[AVESTP_LOGV], phi); /* g */// nicht gatternr ; Sign[0] = 1.0; double phase = q[AVERAGE_YPHASE] + q[AVERAGE_YFREQ] * (f - t); // Y Sign[1] = phase > 0.0 ? 1.0 : phase < 0.0 ? -1.0 : 0.0; v[1] = log(fabs(phase)); } int check_shapeave(cov_model *cov) { if (cov->sub[AVE_GAUSS] == NULL) SERR1("both submodels must be set to '%s'", CovList[GAUSS].nick); cov->mpp.maxheights[0] = RF_NA; return checkave(cov); // !! not next } int init_shapeave(cov_model *cov, gen_storage *s) { ASSERT_GAUSS_METHOD(Average); cov_model *gaussmix = cov->sub[AVE_GAUSS]; double sd, *q = cov->q; bool spacetime = (bool) (PisNULL(AVE_SPACETIME) || P0INT(AVE_SPACETIME)); int err = NOERROR, dim = spacetime ? cov->tsdim - 1 : cov->tsdim; q[AVESTP_V] = 0.0; q[AVESTP_MINEIGEN] = 1.0; q[AVESTP_LOGDET] = 0.0; sd_avestp(cov, s, dim, &sd); // sd->gauss assert(cov->vdim[0] == 1); assert(cov->vdim[0] == cov->vdim[1]); if (cov->mpp.moments >= 0) { cov->mpp.mM[0] = cov->mpp.mMplus[0] = 1.0; if (cov->mpp.moments >= 1) { if ((err = INIT(gaussmix, cov->mpp.moments, s)) != NOERROR) return err; if (cov->mpp.moments >= 2) { cov->mpp.mM[2] = 1.0; } } } return err; } void do_shapeave(cov_model *cov, gen_storage *S) { // Simulation of V; sopee Bernoulli Sec. 4.2 cov_model *aveGAUSS = cov->sub[AVE_GAUSS], *phi = cov->sub[AVE_PHI]; double spec_ret[StpMaxDim], sd, *q = cov->q; bool spacetime = (bool) (PisNULL(AVE_SPACETIME) || P0INT(AVE_SPACETIME)); int dim = spacetime ? cov->tsdim - 1 : cov->tsdim; CovList[phi->nr].drawmix(phi, q + AVESTP_V); // nicht gatternr sd_avestp(cov, S, dim, &sd); // sd->gauss BUG; SPECTRAL(aveGAUSS, S, spec_ret); // nicht gatternr q[AVERAGE_YFREQ] = *spec_ret * q[AVESTP_V]; q[AVERAGE_YPHASE] = TWOPI * UNIFORM_RANDOM; BUG; // what to do with the next line? } /* coxgauss, cmp with nsst1 !! */ // C = 2 (C + 4 M H M), H = h h^t // a = t - h M h - zh // exp(- 0.5 * (h *h + 2 a^2 - mu C mu)) // stimmen die Vorzeichen?? // mu = h - 2 a M h /* cox, cmp with nsst1 !! */ // coxisham #define COX_MU 0 #define COX_D 1 #define COX_BETA 2 void GetEu2Dinv(cov_model *cov, double *x, int dim, double *det, double *Eu2Dinv, double *newxsq, double *newx, double *z) { double y[CoxMaxDim], *V = P(COX_MU), *D= P(COX_D), beta = P0(COX_BETA), t = x[dim], t2 = pow(fabs(t), beta); // standard t^2 int d, dimP1 = dim + 1, dimsq = dim * dim; for (d=0; dtsdim - 1; break; case COX_D : *nc = *nr = cov->tsdim - 1; break; case COX_BETA : *nc = *nr = 1; break; default: *nc = *nr = -1; } } void cox(double *x, cov_model *cov, double *v) { cov_model *next = cov->sub[0]; int dim = cov->tsdim - 1, dimsq = dim * dim; double det, newx, newxsq; ALLOC_EXTRA(Eu2Dinv, dimsq); GetEu2Dinv(cov, x, dim, &det, Eu2Dinv, &newxsq, &newx, NULL); COV(&newx, next, v); *v /= sqrt(det); } void coxhess(double *x, cov_model *cov, double *v) { cov_model *next = cov->sub[0]; int tsdim = cov->tsdim, dim = tsdim - 1, dimsq = dim * dim; double z[CoxMaxDim], det, newx, newxsq, phiD, phiD2; ALLOC_EXTRA(Eu2Dinv, dimsq); GetEu2Dinv(cov, x, dim, &det, Eu2Dinv, &newxsq, &newx, z); Abl2(&newx, next, &phiD2); if (newxsq == 0.0) { cpyUf(Eu2Dinv, phiD2 / sqrt(det), dim, tsdim, v); } else { Abl1(&newx, next, &phiD); cpyUf(Eu2Dinv, phiD / (sqrt(det) * newx), dim, tsdim, v); addzzT(v, (phiD2 - phiD/newx) / (sqrt(det) * newxsq), z, dim, tsdim); } } void coxnabla(double *x, cov_model *cov, double *v) { cov_model *next = cov->sub[0]; int d, tsdim = cov->tsdim, dim = tsdim - 1, dimsq=dim * dim; double z[CoxMaxDim], det, newx, newxsq, phiD, factor; ALLOC_EXTRA(Eu2Dinv, dimsq); GetEu2Dinv(cov, x, dim, &det, Eu2Dinv, &newxsq, &newx, z); if (newxsq == 0.0) { for (d=0; d<=dim; d++) v[d] = 0.0; } else { newx = sqrt(newxsq); Abl1(&newx, next, &phiD); factor = phiD / (det * newx); for (d=0; dsub[0]; int err, i, dim = cov->tsdim - 1, dimsq = dim * dim; if (cov->xdimown < 2) SERR("The space-time dimension must be at least 2."); if (cov->ncol[COX_MU] != 1 || cov->nrow[COX_MU] != dim) { if (cov->ncol[COX_MU] == dim && cov->nrow[COX_MU] == 1) { cov->nrow[COX_MU] = dim; cov->ncol[COX_MU] = 1; } else { SERR3("mu is not given or not a vector of dimen. %d (nrow=%d ncol=%d)", dim, cov->nrow[COX_MU], cov->ncol[COX_MU]); } } // is matrix positive definite? if (PisNULL(COX_D)) { PALLOC(COX_D, dim, dim); for (i=0; irole // ROLE_COV changed 20.7.14 wg spectral )) != NOERROR) return err; if (cov->tsdim != 3) cov->pref[SpectralTBM] = PREF_NONE;; next->delflag = DEL_COV; // set gatternr=nr, since non-negativity ensured if (!isNormalMixture(next->monotone)) return ERRORNORMALMIXTURE; if (CovList[next->nr].spectral == NULL) return ERRORSPECTRAL; // nicht gatternr // no setbackard updatepref(cov, next); if (P0(COX_BETA) != 2.0) cov->pref[SpectralTBM] = 0; cov->hess = true; EXTRA_STORAGE; return NOERROR; } void rangecox(cov_model VARIABLE_IS_NOT_USED *cov, range_type* range){ range->min[COX_MU] = RF_NEGINF; range->max[COX_MU] = RF_INF; range->pmin[COX_MU] = -100.0; range->pmax[COX_MU] = +100.0; range->openmin[COX_MU] = true; range->openmax[COX_MU] = true; range->min[COX_D] = RF_NEGINF; range->max[COX_D] = RF_INF; range->pmin[COX_D] = -100.0; range->pmax[COX_D] = +100.0; range->openmin[COX_D] = false; range->openmax[COX_D] = false; range->min[COX_BETA] = 0.0; range->max[COX_BETA] = 2.0; range->pmin[COX_BETA] = 0.1; range->pmax[COX_BETA] = 2.0; range->openmin[COX_BETA] = true; range->openmax[COX_BETA] = false; } int initcox(cov_model *cov, gen_storage *s) { ASSERT_GAUSS_METHOD(SpectralTBM); cov_model *next = cov->sub[0]; return INIT(next, 0, s); } void spectralcox(cov_model *cov, gen_storage *s, double *e) { cov_model *next = cov->sub[0]; int d, dim = cov->tsdim - 1; double t, v[CoxMaxDim], *V = P(COX_MU), rho= P0(COX_D); SPECTRAL(next, s, e); // nicht gatternr v[0] = rnorm(0.0, INVSQRTTWO); v[1] = rho * v[0] + sqrt(1.0 - rho * rho) * rnorm(0.0, INVSQRTTWO); for (t = 0.0, d=0; dtsdim : 1; *nr = i < CovList[cov->nr].kappas ? cov->tsdim : -1; } void stp(double *x, double *y, cov_model *cov, double *v) { int d, j, k, dim =cov->tsdim, dimsq = dim * dim; double h[StpMaxDim], Mh[StpMaxDim], hSx[StpMaxDim], Syh[StpMaxDim], xi2x, xi2y, detA, hMh, cxy, zh, Q, Amux[StpMaxDim], Amuy[StpMaxDim], *Sc = P(STP_S), *M = P(STP_M), *z = P(STP_Z); cov_model *phi = cov->sub[STP_PHI], *Sf = cov->kappasub[STP_S], *xi2 =cov->sub[STP_XI2]; ALLOC_EXTRA(Sx, dimsq); ALLOC_EXTRA2(Sy, dimsq); ALLOC_EXTRA3(A, dimsq); if (Sf != NULL) { FCTN(x, Sf, Sx); // symmetric, pos definite !! FCTN(y, Sf, Sy); // // if (false) { // int ii; // printf("x=%f %f y=%f %f\n", x[0], x[1], y[0], y[1]); //for (ii=0; ii<4; ii++) printf("%f ", Sx[ii]); // printf("\n"); // for (ii=0; ii<4; ii++) printf("%f ", Sy[ii]); // printf("\n"); // } } else { int bytes = sizeof(double) * dimsq; MEMCOPY(Sx, Sc, bytes); MEMCOPY(Sy, Sc, bytes); } if (xi2 != NULL) { FCTN(x, xi2, &xi2x); FCTN(y, xi2, &xi2y); } else { xi2x = xi2y = 0.0; } for (k=0, d=0; dgatternr].aux_cov) != NULL) auxcf(x, y, Q, phi, v); else FCTN(&Q, phi, v); double dx = detU(Sx, dim), dy = detU(Sy, dim); *v *= pow(2.0, 0.5 * double(dim)) * pow(dx * dy / (detA * detA), 0.25); } int checkstp(cov_model *cov){ cov_model *phi = cov->sub[STP_PHI], *Sf = cov->kappasub[STP_S], *xi2 =cov->sub[STP_XI2]; int err, dim = cov->tsdim; ASSERT_CARTESIAN; if (dim > StpMaxDim) SERR2("For technical reasons max. dimension for ave is %d. Got %d.", StpMaxDim, cov->xdimprev); if (PisNULL(STP_S) && Sf==NULL) { // Sc if ((cov->px[STP_S] = EinheitsMatrix(dim)) == NULL) return ERRORMEMORYALLOCATION; cov->ncol[STP_S] = cov->nrow[STP_S] = dim; } if (PisNULL(STP_M)) { // M if ((cov->px[STP_M] = EinheitsMatrix(dim)) == NULL) return ERRORMEMORYALLOCATION; cov->ncol[STP_M] = cov->nrow[STP_M] = dim; } if (PisNULL(STP_Z)) { // z PALLOC(STP_Z, dim, 1); } if (cov->xdimprev != cov->tsdim) // || cov->xdimprev != cov->tsdim) return ERRORDIM; if ((err = CHECK(phi, dim, 1, PosDefType, XONLY, ISOTROPIC, SCALAR, cov->role // ROLE_COV changed 20.7.14 wg spectral )) != NOERROR) return err; if (!isNormalMixture(phi->monotone)) return ERRORNORMALMIXTURE; cov->pref[Average] = 5; if (Sf != NULL) { if ((err = CHECK(Sf, dim, dim, ShapeType, XONLY, CARTESIAN_COORD, dim, cov->role // ROLE_COV changed 20.7.14 wg spectral )) != NOERROR) return err; } if (xi2 != NULL) { if ((err = CHECK(xi2, dim, dim, ShapeType, XONLY, CARTESIAN_COORD, SCALAR, cov->role // ROLE_COV changed 20.7.14 wg spectral )) != NOERROR) return err; } // kein setbackward?? EXTRA_STORAGE; cov->mpp.maxheights[0] = RF_NA; return NOERROR; } void rangestp(cov_model VARIABLE_IS_NOT_USED *cov, range_type* range){ int i; for (i=0; i<=2; i++) { /* S, M, z */ range->min[i] = RF_NEGINF; range->max[i]= RF_INF; range->pmin[i] = -1e10; range->pmax[i] = 1e10; range->openmin[i] = true; range->openmax[i] = true; } } int structStp(cov_model *cov, cov_model **newmodel) { cov_model *shape; int err; ASSERT_NEWMODEL_NOT_NULL; if (cov->role != Average) ILLEGAL_ROLE; if ((err = covCpy(newmodel, cov)) != NOERROR) return err; shape = *newmodel; shape->nr = SHAPESTP; addModel(shape, STP_GAUSS, GAUSS); shape->sub[STP_GAUSS]->tsdim = 1; return NOERROR; } int check_shapestp(cov_model *cov) { if (cov->sub[AVE_GAUSS] == NULL) SERR1("both submodels must be set to '%s'", CovList[GAUSS].nick); EXTRA_STORAGE; return checkstp(cov); // !! not next } int init_shapestp(cov_model *cov, gen_storage *s) { ASSERT_GAUSS_METHOD(Average); cov_model *Sf = cov->kappasub[STP_S], *gaussmix = cov->sub[STP_GAUSS]; double sd, *q = cov->q; int err = NOERROR; if (Sf != NULL) { double minmax[2]; assert(CovList[Sf->nr].minmaxeigenvalue != NULL); CovList[Sf->nr].minmaxeigenvalue(Sf, minmax); if (minmax[0] <= 0.0) ERR("neg eigenvalue in shape function of 'stp'"); q[AVESTP_MINEIGEN] = minmax[0]; q[AVESTP_LOGDET] = (double) cov->xdimprev * log(minmax[1]); } else { #define dummyN (5 * StpMaxDim) double value[StpMaxDim], ivalue[StpMaxDim], dummy[dummyN], det, min = RF_INF; int i, Ferr, dim = cov->tsdim, ndummy = dummyN; F77_NAME(dgeev)("No", "No", &dim, P(STP_S), &dim, value, ivalue, NULL, &dim, NULL, &dim, dummy, &ndummy, &Ferr); if (Ferr != 0) SERR("error in F77 function call"); det = 1.0; for (i=0; i v) min = v; } q[AVESTP_MINEIGEN] = min; q[AVESTP_LOGDET] = log(det); } q[AVESTP_LOGV] = 0.0; q[AVESTP_LOGMIXDENS] = 0.0; sd_avestp(cov, s, cov->tsdim, &sd); // sd->gauss assert(cov->vdim[0] == 1); assert(cov->vdim[0] == cov->vdim[1]); if (cov->mpp.moments >= 0) { cov->mpp.mM[0] = cov->mpp.mMplus[0] = 1.0; //// ??? notwendig if (cov->mpp.moments >= 1) { if ((err = INIT(gaussmix, 2, s)) != NOERROR) return err; if (cov->mpp.moments >= 2) cov->mpp.mM[2] = 1.0; } } return err; } void do_shapestp(cov_model *cov, gen_storage *s) { // Simulation of V; see Bernoulli Sec. 4.2 cov_model *stpGAUSS = cov->sub[STP_GAUSS], *phi = cov->sub[STP_PHI]; double spec_ret[StpMaxDim], sd, *q = cov->q; CovList[phi->nr].drawmix(phi, &(q[AVESTP_V])); sd_avestp(cov, s, cov->tsdim, &sd); // sd->gauss BUG; SPECTRAL(stpGAUSS, s, spec_ret); // nicht gatternr q[AVERAGE_YFREQ] = *spec_ret * sqrt(q[AVESTP_V]); q[AVERAGE_YPHASE] = TWOPI * UNIFORM_RANDOM; BUG; /// what to do with the next line? // info->logdens = CovList[phi->nr].logmixdens(ZERO, q[AVESTP_LOGV], phi); //info->radius = RF_INF; // info-sd s.o. } void logshapestp(double *x, double *u, cov_model *cov, double *v, double *Sign){ // kann um ca. Faktor 2 beschleunigt werden, wenn // Sx , logdetU, Hx fuer alle x abgespeichert werden // und die Werte dann aus dem Speicher gelesen werden // jedoch sehr Speicherintensiv. MEMCOPY braucht man auch nicht cov_model *Sf = cov->kappasub[STP_S], *xi2 =cov->sub[STP_XI2]; int j, k, d, dim= cov->xdimprev, dimsq = dim * dim, bytes = sizeof(double) * dimsq; double h[StpMaxDim], hSxh, hSx, xi, Mhd, *Sc = P(STP_S), *M = P(STP_M), *z = P(STP_Z), *q = cov->q; ALLOC_EXTRA(Sx, dimsq); if (Sf == NULL) { MEMCOPY(Sx, Sc, bytes); } else { FCTN(x, Sf, Sx); // symmetric, pos definite !! } if (xi2 == NULL) { xi = 0.0; } else { FCTN(x, xi2, &xi); } for (k=0, d=0; dnr].logmixdens(x, q[AVESTP_LOGV], phi) // g //nicht gatternr // - 0.5 * cov_a->logdens // f ; // 1 / sqrt(f) if (!(exponent < 5.0) && PL >= PL_DETAILS) { if (!(exponent < 6.0)) // could be NA, too PRINTF("\n%f logDetU=%f %f expon=%f", 0.25 * dim * (// M_LN2 + ??? !!! Rechnung!!! q[AVESTP_LOGV] - 2.0 * M_LN_SQRT_PI) // (2V/pi)^{d/4} , 0.25 * log(detU(Sx, dim)) /// Sx ^1/4 , -q[AVESTP_V]* hSxh // exp(-V(U-x) S (U-x)) // , CovList[phi->nr].logmixdens(x, q[AVESTP_LOGV], phi)// g //, - 0.5 * cov_a->logdens // f , exponent); else PRINTF("!"); }; assert(exp(exponent) < 10000000.0); double cos_value = cos(q[AVERAGE_YPHASE] + q[AVERAGE_YFREQ] * xi); *v = exponent + log(fabs(cos_value)) ; // Y *Sign = cos_value > 0.0 ? 1.0 : cos_value < 0.0 ? -1.0 : 0.0; } /* Whittle-Matern or Whittle or Besset */ #define RATIONAL_A 0 #define RATIONAL_a 1 void kappa_rational(int i, cov_model *cov, int *nr, int *nc){ *nc = (i == RATIONAL_A) ? cov->tsdim : 1; *nr = (i == RATIONAL_A) ? cov->tsdim : (i==RATIONAL_a) ? 2 : -1; } void minmaxEigenrational(cov_model *cov, double *mm) { double *a = P(RATIONAL_a); if (a[0] < a[1]) { mm[0] = a[0]; mm[1] = a[1]; } else { mm[0] = a[1]; mm[1] = a[0]; } } double maxEigenrational(cov_model VARIABLE_IS_NOT_USED *cov, double VARIABLE_IS_NOT_USED *mm) { double *a = P(RATIONAL_a); return (a[0] > a[1]) ? a[0] : a[1]; } void rational(double *x, cov_model *cov, double *v) { int i, k, j, dim = cov->tsdim; double nu, *A = P(RATIONAL_A), *a = P(RATIONAL_a); nu = 0.0; for (k=0, i=0; inrow[RATIONAL_a] == 1) { double dummy = P0(RATIONAL_a); PFREE(RATIONAL_a); PALLOC(RATIONAL_a, 2, 1); P(RATIONAL_a)[0] = dummy; P(RATIONAL_a)[1] = 0.0; } if ((err = checkkappas(cov)) != NOERROR) return err; cov->mpp.maxheights[0] = P(RATIONAL_a)[0] > P(RATIONAL_a)[1] ? P(RATIONAL_a)[0] : P(RATIONAL_a)[1]; return NOERROR; } void rangerational(cov_model VARIABLE_IS_NOT_USED *cov, range_type* range){ range->min[RATIONAL_A] = RF_NEGINF; range->max[RATIONAL_A] = RF_INF; range->pmin[RATIONAL_A] = -1e10; range->pmax[RATIONAL_A] = 1e10; range->openmin[RATIONAL_A] = true; range->openmax[RATIONAL_A] = true; range->min[RATIONAL_a] = 0.0; range->max[RATIONAL_a] = RF_INF; range->pmin[RATIONAL_a] = 0.0; range->pmax[RATIONAL_a] = 10; range->openmin[RATIONAL_a] = false; range->openmax[RATIONAL_a] = true; } // Sigma(x) = diag>0 + A'xx'A #define EAXXA_E 0 #define EAXXA_A 1 #define ETAXXA_ALPHA 2 void kappa_EAxxA(int i, cov_model *cov, int *nr, int *nc){ *nc = (EAXXA_A == i) ? cov->tsdim : 1; *nr = i < CovList[cov->nr].kappas ? cov->tsdim : -1; } void EAxxA(double *x, cov_model *cov, double *v) { int d, k, j, dim = cov->tsdim; double xA[EaxxaMaxDim], *E = P(EAXXA_E), *A = P(EAXXA_A); for (k=0, d=0; dtsdim; for (mm[0] = RF_INF, mm[1]=RF_NEGINF, i=0; i mm[1]) mm[1] = E[i]; } } int checkEAxxA(cov_model *cov){ int err; if (cov->xdimown > EaxxaMaxDim) SERR2("For technical reasons max. dimension for ave is %d. Got %d.", EaxxaMaxDim, cov->xdimown); if ((err = checkkappas(cov)) != NOERROR) return err; cov->vdim[0] = cov->vdim[1] = cov->tsdim; cov->mpp.maxheights[0] = RF_NA; return NOERROR; } void rangeEAxxA(cov_model VARIABLE_IS_NOT_USED *cov, range_type* range){ range->min[EAXXA_E] = 0.0; range->max[EAXXA_E] = RF_INF; range->pmin[EAXXA_E] = 0.0001; range->pmax[EAXXA_E] = 10; range->openmin[EAXXA_E] = true; range->openmax[EAXXA_E] = true; range->min[EAXXA_A] = RF_NEGINF; range->max[EAXXA_A] = RF_INF; range->pmin[EAXXA_A] = -1e10; range->pmax[EAXXA_A] = 1e10; range->openmin[EAXXA_A] = true; range->openmax[EAXXA_A] = true; } // Sigma(x) = diag>0 + A'xx'A void kappa_EtAxxA(int i, cov_model VARIABLE_IS_NOT_USED *cov, int *nr, int *nc){ int tsdim = 3; *nc = (i == EAXXA_A) ? tsdim : 1; *nr = (i == EAXXA_E || i==EAXXA_A) ? tsdim : (i==ETAXXA_ALPHA) ? 1 : -1; } void EtAxxA(double *x, cov_model *cov, double *v) { int d, k, j, dim = cov->tsdim, time = dim - 1; double xAR[EaxxaMaxDim], R[9], *E = P(EAXXA_E), *A = P(EAXXA_A), phi = P0(ETAXXA_ALPHA), c = cos(phi * x[time]), s = sin(phi * x[time]); R[0] = R[4] = c; R[1] = s; R[3] = -s; R[2] = R[5] = R[6] = R[7] = 0.0; R[8] = 1.0; { double xA[EaxxaMaxDim]; for (k=0, d=0; dtsdim; for (mm[0] = RF_INF, mm[1]=RF_NEGINF, i=0; i mm[1]) mm[1] = E[i]; } } int checkEtAxxA(cov_model *cov){ int err; if (cov->xdimown != 3) SERR("The space-time dimension must be 3."); cov->vdim[0] = cov->vdim[1] = cov->tsdim; if ((err = checkkappas(cov)) != NOERROR) return err; cov->mpp.maxheights[0] = RF_NA; return NOERROR; } void rangeEtAxxA(cov_model VARIABLE_IS_NOT_USED *cov, range_type* range){ int i; for (i=0; i<=2; i++) { range->min[i] = RF_NEGINF; range->max[i] = RF_INF; range->pmin[i] = -1e10; range->pmax[i] = 1e10; range->openmin[i] = true; range->openmax[i] = true; } range->min[EAXXA_E] = 0.0; range->max[EAXXA_E] = RF_INF; range->pmin[EAXXA_E] = 0.0001; range->pmax[EAXXA_E] = 10; range->openmin[EAXXA_E] = true; range->openmax[EAXXA_E] = true; } // Sigma(x) = diag>0 + A'xx'A #define ROTAT_PHI 0 // both rotat and Rotat #define ROTAT_SPEED 1 void kappa_rotat(int i, cov_model *cov, int *nr, int *nc){ *nc = 1; *nr = i < CovList[cov->nr].kappas ? 1 : -1; } void rotat(double *x, cov_model *cov, double *v) { int dim = cov->tsdim, time = dim - 1; double speed = P0(ROTAT_SPEED), phi = P0(ROTAT_PHI), absx = sqrt(x[0] * x[0] + x[1] * x[1]); *v = (absx == 0.0) ? 0.0 : speed * (cos(phi * x[time]) * x[0] + sin(phi * x[time]) * x[1]) / absx; } void minmaxEigenrotat(cov_model VARIABLE_IS_NOT_USED *cov, double *mm) { mm[0] = -1; mm[1] = 1; } int checkrotat(cov_model *cov){ int err; if (cov->xdimown != 3) SERR("The space-time dimension must be 3."); if ((err = checkkappas(cov)) != NOERROR) return err; cov->mpp.maxheights[0] = RF_NA; return NOERROR; } void rangerotat(cov_model VARIABLE_IS_NOT_USED *cov, range_type* range){ int i; for (i=0; i<2; i++) { range->min[i] = RF_NEGINF; range->max[i] = RF_INF; range->pmin[i] = -1e10; range->pmax[i] = 1e10; range->openmin[i] = true; range->openmax[i] = true; } } // Sigma(x) = diag>0 + A'xx'A void kappa_Rotat(int i, cov_model *cov, int *nr, int *nc){ *nc = 1; *nr = i < CovList[cov->nr].kappas ? 1 : -1; } void Rotat(double *x, cov_model *cov, double *v) { int d, k, j, dim = cov->tsdim, time = dim - 1; double phi = P0(ROTAT_PHI), c = cos(phi * x[time]), s = sin(phi * x[time]), R[9]; assert(dim ==3); R[0] = R[4] = c; R[1] = s; R[3] = -s; R[2] = R[5] = R[6] = R[7] = 0.0; R[8] = 1.0; for (k=0, d=0; dxdimown != 3) SERR("The space-time dimension must be 3."); if ((err = checkkappas(cov)) != NOERROR) return err; cov->vdim[0] = cov->vdim[1] = cov->tsdim; cov->mpp.maxheights[0] = RF_NA; return NOERROR; } void rangeRotat(cov_model VARIABLE_IS_NOT_USED *cov, range_type* range){ range->min[ROTAT_PHI] = RF_NEGINF; range->max[ROTAT_PHI] = RF_INF; range->pmin[ROTAT_PHI] = -1e10; range->pmax[ROTAT_PHI] = 1e10; range->openmin[ROTAT_PHI] = true; range->openmax[ROTAT_PHI] = true; } /* nsst */ /* Tilmann Gneiting's space time models, part I */ void nsst(double *x, cov_model *cov, double *v) { cov_model *subphi = cov->sub[0]; cov_model *subpsi = cov->sub[1]; double v1, v2, psi, y; COV(ZERO, subpsi, &v1); COV(x + 1, subpsi, &v2); psi = sqrt(1.0 + v1 - v2); // C0 : C(0) oder 0 // Cx : C(x) oder -gamma(x) y = x[0] / psi; COV(&y, subphi, v); *v *= pow(psi, -P0(NSST_DELTA)); } void Dnsst(double *x, cov_model *cov, double *v) { cov_model *subphi = cov->sub[0]; cov_model *subpsi = cov->sub[1]; double v1, v2, psi, y; COV(ZERO, subpsi, &v1); COV(x + 1, subpsi, &v2); psi = sqrt(1.0 + v1 - v2); // C0 : C(0) oder 0 // Cx : C(x) oder -gamma(x) y = x[0] / psi; Abl1(&y, subphi, v); *v *= pow(psi, -P0(NSST_DELTA) - 1.0); } void TBM2nsst(double *x, cov_model *cov, double *v) { cov_model *subphi = cov->sub[0]; cov_model *subpsi = cov->sub[1]; double v1, v2, psi, y; assert(false); COV(ZERO, subpsi, &v1); COV(x + 1, subpsi, &v2); psi = sqrt(1.0 + v1 - v2); // C0 : C(0) oder 0 // Cx : C(x) oder -gamma(x) y = x[0] / psi; TBM2CALL(&y, subphi, v); *v *= pow(psi, -P0(NSST_DELTA)); } int checknsst(cov_model *cov) { cov_model *subphi = cov->sub[0]; cov_model *subpsi = cov->sub[1]; int err; if (cov->xdimown != 2) SERR("reduced dimension must be 2"); if ((err = checkkappas(cov)) != NOERROR) return err; cov->finiterange = false; if ((err = CHECK(subphi, cov->tsdim, 1, PosDefType, XONLY, ISOTROPIC, SCALAR, cov->role // ROLE_COV changed 20.7.14 wg spectral )) != NOERROR) return err; if (!isNormalMixture(subphi->monotone)) return(ERRORNORMALMIXTURE); setbackward(cov, subphi); assert(cov->finiterange != true); // if ((err = CHECK(subpsi, 1, 1, VariogramType, XONLY, ISOTROPIC, SCALAR, cov->role // ROLE_COV changed 20.7.14 wg spectral )) != NOERROR) return err; subphi->delflag = subpsi->delflag = DEL_COV-20; // kein setbackward(cov, subpsi); return NOERROR; } void rangensst(cov_model *cov, range_type* range){ range->min[NSST_DELTA] = cov->tsdim - 1; range->max[NSST_DELTA] = RF_INF; range->pmin[NSST_DELTA] = cov->tsdim - 1; range->pmax[NSST_DELTA] = 10.0; range->openmin[NSST_DELTA] = false; range->openmax[NSST_DELTA] = true; } /* gennsst */ /* generalisation in schlather, bernoulli 2010 */ #define GENNSST_INTERN_A 0 void kappa_gennsst_intern(int i, cov_model VARIABLE_IS_NOT_USED *cov, int *nr, int *nc){ *nc = *nr = i == 0 ? 0 : -1; } void nonstatgennsst_intern(double *x,double *y, cov_model *cov, double *v) { cov_model *next = cov->sub[0]; double det, z, *A = P(GENNSST_INTERN_A); int d, dim = cov->tsdim; ALLOC_EXTRA(ds, dim); // printf("\nx=%f %f %f \ny=%f %f %f\nz=%f %f %f\n %f %f %f\n %f %f %f\n", x[0], x[1], x[2], y[0],y[1],y[2], A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[8]); // PMI(cov->calling->sub[1]); det_UpperInv(A, &det, dim); for (d=0; dCartesian->isotropic hinzubekommen // und ^- hier noch mit A zu multiplizieren cov_model *next = cov->sub[0]; int err, dim = cov->xdimown; assert(cov->tsdim == cov->xdimown); if ((err = CHECK(next, cov->tsdim, 1, PosDefType, XONLY, ISOTROPIC, SCALAR, cov->role )) != NOERROR) return err; if (!isNormalMixture(next->monotone)) return ERRORNORMALMIXTURE; //APMI(cov->calling); if (PisNULL(GENNSST_INTERN_A)) { PALLOC(GENNSST_INTERN_A, dim, dim); } else if (cov->nrow[GENNSST_INTERN_A] != dim) { PFREE(GENNSST_INTERN_A); PALLOC(GENNSST_INTERN_A, dim, dim); } cov->finiterange = false; setbackward(cov, next); assert(!cov->finiterange); cov->vdim[0] = cov->vdim[1] = 1; EXTRA_STORAGE; return NOERROR; } void range_gennsst_intern(cov_model VARIABLE_IS_NOT_USED *cov, range_type* range){ range->min[GENNSST_INTERN_A] = RF_NEGINF; range->max[GENNSST_INTERN_A] = RF_INF; range->pmin[GENNSST_INTERN_A] = -100.0; range->pmax[GENNSST_INTERN_A] = +100.0; range->openmin[GENNSST_INTERN_A] = true; range->openmax[GENNSST_INTERN_A] = true; } #define GENNSST_DELTA 0 void nonstatgennsst(double *x,double *y, cov_model *cov, double *v) { cov_model *subphi = cov->key; cov_model *subpsi = cov->sub[1]; int i, dim = cov->tsdim, dimSq = dim * dim; // print("A %s\n", TYPENAMES[subpsi->typus]); NONSTATCOV(x, y, subpsi, PARAM(subphi, GENNSST_INTERN_A)); if (isVariogram(subpsi)) { ALLOC_EXTRA(z, dimSq); NONSTATCOV(ZERO, ZERO, subpsi, z); for (i=0; itypus != NegDefType) BUG; // print("%f %f %f %f dim = %d %f %f %f %f %s\n", x[0], x[1], y[0], y[1], dim, v1[0], v1[1], v1[2], v1[3],NAME(subpsi)); NONSTATCOV(x, y, subphi, v); } int checkgennsst(cov_model *cov) { cov_model *subphi = cov->sub[0]; cov_model *subpsi = cov->sub[1]; #define ncs 3 int err, UCS = UpgradeToCoordinateSystem(cov->isoown); assert(cov->tsdim == cov->xdimown); if (cov->q == NULL) { QALLOC(1); cov->q[0]=NOERROR; } if (isSpherical(cov->isoown)) return cov->q[0]!=NOERROR ? (int) cov->q[0] : ERRORFAILED; if (UCS == ISO_MISMATCH) return cov->q[0]!=NOERROR ? (int) cov->q[0] : ERRORODDCOORDTRAFO; if (cov->xdimown != cov->tsdim) SERR("logical and physical dimension differ"); //STOPAFTER(cov->isoown==EARTH_COORD || true, PMI(cov)); // assert(cov->isoown ==EARTH_ISOTROPIC || __stopafter__ ==1); if (cov->key == NULL) { if ((err = covCpy(&(cov->key), subphi)) != NOERROR) return err; addModel(&(cov->key), GENNSST_INTERN); } if ((cov->q[0] =err = CHECK(cov->key, cov->tsdim, cov->tsdim, PosDefType, KERNEL, SYMMETRIC, // viel zu schwach, geht aber // z.Zt. nicht anders // hinsichtlich der Koordinatentransformation // -- wird das interne modell abgefangen SCALAR, cov->role )) != NOERROR) { return err; } // PL = GLOBAL.general.Cprintlevel = 7; // MUSSS ZWINGEND ALS ZWEITES KOMMEN if ((err = CHECK(subpsi, cov->tsdim, cov->tsdim, NegDefType, KERNEL, UCS, cov->key->xdimown, cov->role)) != NOERROR) { return err; } cov->finiterange = false; setbackward(cov, cov->key); assert(!cov->finiterange); // cov->vdim[0] = cov->vdim[1] = 1; EXTRA_STORAGE; COV_DELETE(cov->sub + 0); if ((err = covCpy(cov->sub + 0, cov->key->sub[0])) != NOERROR) BUG; cov->sub[0]->calling = cov; // PMI(cov->calling); assert(err == NOERROR);BUG; // ERR(err); BUG; // kein setbackward(cov, subpsi); return NOERROR; }