/* Authors Martin Schlather, martin.schlather@math.uni-goettingen.de Copyright (C) 2006 -- 2011 Martin Schlather Definition of correlation functions and derivatives (spectral densities, etc) of genuinely anisotropic or non-stationary functions * Never use the below functions directly, but only by the functions indicated in RFsimu.h, since there is no error check (e.g. initialization of RANDOM) * VARIANCE, SCALE may not be used here since these parameters are already considered elsewhere 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 2 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 "RF.h" #include "Covariance.h" #include #include void xA(double *x, double*A, int nrow, int ncol, double *y) { int i,j,k; for (k=i=0; itsdim-1, nr, nc); } void kappa_ave2(int i, cov_model *cov, int *nr, int *nc){ kappa_ave(i, cov->tsdim, nr, nc); } void rangeave(int dim, range_arraytype* ra) { range_type *range = ra->ranges; int i; for (i=0; i<=1; i++) { range->min[i] = RF_NEGINF; range->max[i] = RF_INF; range->pmin[i] = -10.0; range->pmax[i] = 10.0; range->openmin[i] = true; range->openmax[i] = true; } } void rangeave1(cov_model *cov, range_arraytype* ra){ rangeave(cov->tsdim - 1, ra); } void rangeave2(cov_model *cov, range_arraytype* ra){ rangeave(cov->tsdim , ra); } int checkave(cov_model *cov, int dim, const char *msg) { cov_model *next = cov->sub[0]; int i, j, err; // dimP1 = dim + 1; double *A = cov->p[0]; // char Msg[255]; // cov_fct *CN = CovList + next->nr; assert(cov->xdim == cov->tsdim); if (cov->xdim > AveMaxDim) { sprintf(ERRORSTRING, "For technical reasons max. dimension for ave is %d. Got %d.", AveMaxDim, cov->xdim); return ERRORM + 2; } if (CovList[cov->nr].avef != 0) cov->pref[Average] = cov->user[Average]; cov->manipulating_x=true; if (cov->ncol[0] != dim || cov->nrow[0] != dim) { sprintf(ERRORSTRING, "A not %sx%s matrix, but %dx%d (dim=%d)", msg, msg, cov->ncol[0], cov->nrow[0], dim); return ERRORM + 2; } if (cov->ncol[1] != 1 || cov->nrow[1] != dim) { sprintf(ERRORSTRING, "z not (%s)-dim vector", msg); return ERRORM + 3; } for (i=0; itsdim = DEL_COV; // delete GATTER, since non-negativity ensured if (!next->normalmix) ERR("sub model is not a normal mixture model"); if (CovList[next->nr].spectral == NULL) ERR("submodel does not have spectral representation"); // updatepref(cov, next); ## gute idee? if (next->pref[SpectralTBM] == PREF_NONE) cov->pref[RandomCoin] = PREF_NONE; return NOERROR; } int checkave1(cov_model *cov) { return checkave(cov, cov->tsdim - 1, "d-1"); } int checkave2(cov_model *cov) { return checkave(cov, cov->tsdim, "d"); } void ave(double *h, cov_model *cov, double cstart, int dim, double *v) { // f = uAu +zu; M = id; cov_model *next = cov->sub[0]; int i,j,k,d; // dimP1 = dim + 1; double detMB, Ah[AveMaxDim],MB[AveMaxDim], Dh[AveMaxDim], dummy, c, hMh, *A = cov->p[0], *z = cov->p[1]; c = cstart; hMh = 0.0; for (k=d=0; dnr].cov(&y, next, v); *v /= sqrt(detMB); } void ave1(double *x, cov_model *cov, double *v) { // example 13 int dim = cov->tsdim - 1; ave(x, cov, x[dim] /* t */, dim, v); } void ave2(double *x, cov_model *cov, double *v) { // no counterpart exists int dim = cov->tsdim; ave(x, cov, 0.0 /* t */, dim, v); } void sd_standard(mpp_storage *s, cov_model *cov){ int d; double x2; for (x2=0.0, d=0; ddim; d++) x2 += s->lensimu[d] * s->lensimu[d]; x2 = sqrt(x2); for (d=0; ddim; d++) s->sdgauss[d] = x2; } void sd_ave_stp(mpp_storage *s, cov_model *cov){ int d; double b, alphamin, x2, InvSqrt2a, V = s->invscale; for (x2=0.0, d=0; ddim; d++) x2 += s->lensimu[d] * s->lensimu[d]; x2 *= 0.25; b = 3 * V * s->c[MPP_EIGEN] * x2 / s->dim; alphamin = (4.0 + 4.0 * b - 2.0 * sqrt(4 * b * b + 8.0 * b + 1)) / 3; InvSqrt2a = 1.0 / sqrt(2.0 * alphamin * 6 * V); for (d=0; ddim; d++) s->sdgauss[d] = InvSqrt2a; // printf("%f\n", InvSqrt2a);assert(false); } cov_model aveGAUSS; void mppinit_ave(mpp_storage *s, cov_model *cov, int dim) { cov_model *next = covOhneGatter(cov->sub[0]); assert(next->tsdim == 1); s->c[DRAWMIX_EXPONENT] = 0.25 * dim; COV_NULL(&aveGAUSS); aveGAUSS.nr = GAUSS; aveGAUSS.tsdim = 1; CovList[aveGAUSS.nr].initspectral(&aveGAUSS); // s->rsq = -0.5 * s->logapproxzero; // -0.5 * log(approxzero) s->rsq = - s->logapproxzero; // -0.5 * log(approxzero) // rsq: radius^2 ab dem Gaussglocke auf 0 gesetzt wird s->r = s->effectiveRadius = sqrt(s->rsq); s->integral = gaussInt(dim, 1, 1.0, s->effectiveRadius); // 1. Moment s->integralsq = gaussInt(dim, 2, 1.0, s->effectiveRadius); // 2. Moment } void mppinit_ave1(mpp_storage *s, cov_model *cov) { mppinit_ave(s, cov, cov->tsdim-1); } void mppinit_ave2(mpp_storage *s, cov_model *cov) { mppinit_ave(s, cov, cov->tsdim); } void coin_ave(mpp_storage *s, cov_model *cov){ double spectral[AveMaxDim]; // do never reduce to 1 dimension // since CovList.spectral might use all the components static spectral_storage spec = {0.0, 0.0, false, false}; cov_model *next = covOhneGatter(cov->sub[0]); s->loginvscale = CovList[next->nr].drawlogmix(next, s); // V s->invscale = exp(s->loginvscale); s->c[MPP_EIGEN] = 1.0; // printf(" %ld\n", s->location); s->location(s, cov); // uniform oder Gauss // assert(false); CovList[GAUSS].spectral(&aveGAUSS, &spec, spectral); // dim == 1 !!! s->c[AVE_SPECTRAL] = spectral[0] * sqrt(s->invscale); // dim == 1 !! s->c[AVE_VV] = TWOPI * UNIFORM_RANDOM; } void ave1_logg(double *u, cov_model *cov, int dim, double *logg, double *sign) { // smoothing kernel --- complex call since g could have negative sign // on the other hand, for the intensity lambda of the spatial vector, // lambda^{-1/2} could be very large causing numerical problems if // multivplied with very small g int i; double r2 = 0.0; *logg = *sign = 1.0; return; // print("%d logg\n", dim); for (i=0; ip[0], *z = cov->p[1], value; value = 0.0; for (k=d=0; du; // for (d=0; d < dim; d++) dux[d] = x[d] - u[d]; ave1_logg(dux, cov, dim, &logg, &sign); f = ave1_f(dux, cov, dim); return (res_type) (exp(0.25 * dim * s->loginvscale + s->logInvSqrtDens + logg) * M_SQRT2 * cos(s->c[AVE_VV] + s->c[AVE_SPECTRAL] * (f - t))); // Y } res_type mppget_ave1(double *x, cov_model *cov, mpp_storage *s) { return mppget_ave(x, cov, s, s->dim - 1, x[s->dim-1]); } res_type mppget_ave2(double *x, cov_model *cov, mpp_storage *s) { return mppget_ave(x, cov, s, s->dim, 0.0); } /* 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 void GetEu2Dinv(param_type p, double *x, int dim, double *det, double *Eu2Dinv, double *newxsq, double *newx, double *z) { double t, t2, y[AveMaxDim], *V = p[0], *D= p[1]; int d, dimP1 = dim + 1, dimsq = dim * dim; t = x[dim]; t2 = pow(fabs(t), p[2][0]); // standard t^2 for (d=0; dtsdim - 1; break; case 1 : *nc = *nr = cov->tsdim - 1; break; case 2 : *nc = *nr = 1; break; default: *nc = *nr = -1; } } void cox1(double *x, cov_model *cov, double *v) { cov_model *next = cov->sub[0]; int dim = cov->tsdim - 1, dimsq = dim * dim; double det, newx, *Eu2Dinv, newxsq; Eu2Dinv = (double*) malloc(sizeof(double) * dimsq); GetEu2Dinv(cov->p, x, dim, &det, Eu2Dinv, &newxsq, &newx, NULL); CovList[next->nr].cov(&newx, next, v); *v /= sqrt(det); free(Eu2Dinv); } 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[AveMaxDim], det, *Eu2Dinv, newx, newxsq, phiD, phiD2; Eu2Dinv = (double*) malloc(sizeof(double) * dimsq); GetEu2Dinv(cov->p, x, dim, &det, Eu2Dinv, &newxsq, &newx, z); CovList[next->nr].D2(&newx, next, &phiD2); if (newxsq == 0.0) { cpyUf(Eu2Dinv, phiD2 / sqrt(det), dim, tsdim, v); // printf("%f %f %f\n %f %f %f \n %f %f %f\n Eu2Dinv %f %f %f %f t=%f\n", // v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], // Eu2Dinv[0],Eu2Dinv[1],Eu2Dinv[2],Eu2Dinv[3],x[dim] ); // assert(Eu2Dinv[0] ==1 ); } else { CovList[next->nr].D(&newx, next, &phiD); cpyUf(Eu2Dinv, phiD / (sqrt(det) * newx), dim, tsdim, v); addzzT(v, (phiD2 - phiD/newx) / (sqrt(det) * newxsq), z, dim, tsdim); } free(Eu2Dinv); } 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[AveMaxDim], det, newx, newxsq, *Eu2Dinv, phiD, factor; Eu2Dinv = (double*) malloc(sizeof(double) * dimsq); GetEu2Dinv(cov->p, 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); CovList[next->nr].D(&newx, next, &phiD); factor = phiD / (det * newx); for (d=0; dsub[0]; int err, dim = cov->tsdim - 1; cov->manipulating_x=true; if (cov->ncol[0] != 1 || cov->nrow[0] != dim) { // char Msg[255]; sprintf(ERRORSTRING, "V is not given or not a vector of dimension 2 (nrow1=%d ncol2=%d dim=%d)", cov->nrow[0], cov->ncol[1], dim); return ERRORM; } // is matrix positiv definite? if (!is_positive_definite(cov->p[1], dim)) ERR("D is not (strictly) positive definite."); kdefault(cov, 2, 2.0); if ((err = checkkappas(cov)) != NOERROR) return err; if ((err = check2X(next, dim, 1, STATIONARY, ISOTROPIC, UNIVARIATE)) != NOERROR) return err; next->tsdim = DEL_COV; // delete GATTER, since non-negativity ensured if (!next->normalmix) ERR("submodel is not a normal mixture model"); if (CovList[next->nr].spectral == NULL) ERR("submodel does not have spectral representation"); updatepref(cov, next); if (cov->p[2][0] != 2.0) cov->pref[SpectralTBM] = 0; cov->hess = true; return NOERROR; } void rangecox1(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges; range->min[0] = RF_NEGINF; range->max[0] = RF_INF; range->pmin[0] = -100.0; range->pmax[0] = +100.0; range->openmin[0] = true; range->openmax[0] = true; range->min[1] = RF_NEGINF; range->max[1] = RF_INF; range->pmin[1] = -100.0; range->pmax[1] = +100.0; range->openmin[1] = false; range->openmax[1] = false; range->min[2] = 0.0; range->max[2] = 2.0; range->pmin[2] = 0.1; range->pmax[2] = 2.0; range->openmin[2] = true; range->openmax[2] = false; range->maxdim = CoxMaxDim; } int initspectralcox1(cov_model *cov) { cov_model *next = cov->sub[0]; if (cov->tsdim != 3) return ERRORFAILED; return CovList[next->nr].initspectral(next); } void spectralcox1(cov_model *cov, spectral_storage *s, double *e) { cov_model *next = cov->sub[0]; int d, dim = cov->tsdim - 1; double t, v[CoxMaxDim], *V = cov->p[0], rho= cov->p[1][0]; CovList[next->nr].spectral(next, s, e); v[0] = rnorm(0.0, INVSQRTTWO); v[1] = rho * v[0] + sqrt(1 - rho * rho) * rnorm(0.0, INVSQRTTWO); for (t = 0.0, d=0; dtsdim : 1; *nr = (i <= 2) ? 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], // Q2, Q3, *Sx, *Sy, *A, *Sc = cov->p[0], *M = cov->p[1], *z = cov->p[2]; cov_model *next = cov->sub[0], *Sf = cov->sub[1], *xi2 =cov->sub[2], *H =cov->sub[3]; Sx = (double*) malloc(dimsq * sizeof(double)); Sy = (double*) malloc(dimsq * sizeof(double)); A = (double*) malloc(dimsq * sizeof(double)); if (Sf != NULL) { covfct fct = CovList[Sf->nr].cov; fct(x, Sf, Sx); // symmetric, pos definite !! fct(y, Sf, Sy); } else { int bytes = sizeof(double) * dimsq; memcpy(Sx, Sc, bytes); memcpy(Sy, Sc, bytes); } if (xi2 != NULL) { covfct fct = CovList[xi2->nr].cov; fct(x, xi2, &xi2x); fct(y, xi2, &xi2y); } else { xi2x = xi2y = 0.0; } if (H == NULL) { for (k=0, d=0; dnr].cov; double xx[StpMaxDim], yy[StpMaxDim]; fct(x, H, xx); fct(y, H, yy); for (k=0, d=0; d= 0.0); } Q = sqrt(Q); aux_covfct auxcf; if ((auxcf = CovList[next->nr].aux_cov) != NULL) auxcf(x, y, Q, next, v); else CovList[next->nr].cov(&Q, next, 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); free(Sx); free(Sy); free(A); } int checkstp(cov_model *cov){ cov_model *next = cov->sub[0], *Sf = cov->sub[1], *xi2 =cov->sub[2], *H = cov->sub[3]; int err; int dim = cov->tsdim; // printf("%d %d\n", cov->ncol[0], cov->p[0]); // assert(false); if (cov->xdim > StpMaxDim) { sprintf(ERRORSTRING, "For technical reasons max. dimension for ave is %d. Got %d.", StpMaxDim, cov->xdim); return ERRORMSG; } cov->manipulating_x=true; if (cov->ncol[0] == 0) { // Sc EinheitsMatrix(cov->p, dim); cov->ncol[0] = cov->nrow[0] = dim; } if (cov->ncol[1] == 0) { // M EinheitsMatrix(cov->p, dim); cov->ncol[1] = cov->nrow[1] = dim; } if (cov->ncol[2] == 0) { // z cov->p[2] = (double*) calloc(dim, sizeof(double)); cov->ncol[2] = 1; cov->nrow[2] = dim; } // printf("%d\n", dim); assert(false); if ((err = checkkappas(cov)) != NOERROR) return err; if ((err = check2X(next, 1, 1, COVARIANCE, ANISOTROPIC, UNIVARIATE)) != NOERROR) return err; if (!next->normalmix) ERR("submodel must be a normal scale mixture model"); if (Sf != NULL) { if ((err = check2X(Sf, dim, dim, AUXMATRIX, ANISOTROPIC, dim)) != NOERROR) return err; } if (xi2 != NULL) { if ((err = check2X(xi2, dim, dim, AUXMATRIX, ANISOTROPIC, UNIVARIATE)) != NOERROR) return err; } if (H != NULL) { if ((err = check2X(H, dim, dim, AUXVECTOR, ANISOTROPIC, dim)) != NOERROR) return err; } return NOERROR; } void rangestp(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges + 0; int i; for (i=0; i<=2; i++) { /* S, M */ 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; } } cov_model stpGAUSS; void mppinit_stp(mpp_storage *s, cov_model *cov) { // printf("%d %s\n", cov->p[0], CovList[cov->nr].name); // assert(false); cov_model *Sf = cov->sub[1]; // warning("dadurch dass U von V abhaengt muss eventuell nachkorrigiert werden"); s->effectiveRadius = 0.0; s->effectivearea = 1.0; s->integralpos = RF_NAN; s->integral=0.0; s->integralsq=1.0; // falsch! s->maxheight = RF_NAN; if (Sf != NULL) { realfct eigen = CovList[Sf->nr].mineigenvalue; assert(eigen != NULL); s->c[MPP_EIGEN] = eigen(Sf); } else { double value[StpMaxDim], ivalue[StpMaxDim], dummy[5 * StpMaxDim], min = RF_INF; int i, err, dim = cov->tsdim, ndummy = 5 * dim; // char No = 'N'; // printf("%d %f %f\n", dim, cov->p[0][0], cov->p[0][1]); F77_NAME(dgeev)("No", "No", &dim, cov->p[0], &dim, value, ivalue, NULL, &dim, NULL, &dim, dummy, &ndummy, &err); for (i=0; i value[i]) min = value[i]; } s->c[MPP_EIGEN] = min; } s->c[DRAWMIX_EXPONENT] = 0.25 * cov->tsdim; COV_NULL(&stpGAUSS); stpGAUSS.nr = GAUSS; stpGAUSS.tsdim = 1; CovList[stpGAUSS.nr].initspectral(&stpGAUSS); } void coin_stp(mpp_storage *s, cov_model *cov){ cov_model *next = cov->sub[0]; static spectral_storage spec = {0.0, 0.0, false, false}; double spectral[StpMaxDim]; s->loginvscale = CovList[next->nr].drawlogmix(next, s); // V s->invscale = exp(s->loginvscale); s->location(s, cov); // PrintModelInfo(&stpGAUSS); CovList[GAUSS].spectral(&stpGAUSS, &spec, spectral); // return; s->c[MPP_SPECTRAL] = spectral[0] * sqrt(s->invscale); s->c[MPP_VV] = TWOPI * UNIFORM_RANDOM; if (!(s->c[MPP_SPECTRAL] >= -1e40 && s->c[MPP_SPECTRAL] <1e40)) { PRINTF("%f %f %f %f %f\n", spectral, sqrt(s->invscale), s->loginvscale, s->c[DRAWMIX_ALPHA], s->c[MPP_SPECTRAL]); assert(false); } s->effectiveRadius = s->plus + s->relplus / s->invscale; // printf("coin: %f %f %f\n", s->u[0], s->u[1], s->logInvSqrtDens); } //double *x, double *u, double logInvSqrtDens, double *p, // double *r, logmixtureweight logmixweight res_type mppget_stp(double *x, double*u, cov_model *cov, mpp_storage *s){ // 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. memcpy braucht man auch nicht cov_model *next = cov->sub[0], *Sf = cov->sub[1], *xi2 =cov->sub[2], *H =cov->sub[3]; int j, k, d, dim= s->dim, bytes = sizeof(double) * dim * dim; double h[StpMaxDim], hSxh, hSx, xi, Mhd, *Sx, // *u = s->u, *Sc = cov->p[0], *M = cov->p[1], *z = cov->p[2]; Sx= (double*) malloc(bytes); if (Sf == NULL) { memcpy(Sx, Sc, bytes); } else { CovList[Sf->nr].cov(x, Sf, Sx); // symmetric, pos definite !! } if (xi2 == NULL) { xi = 0.0; } else { CovList[xi2->nr].cov(x, xi2, &xi); } if (H == NULL) { for (k=0, d=0; dnr].cov; double xx[StpMaxDim]; fct(x, H, xx); for (k=0, d=0; dloginvscale - 2.0 * M_LN_SQRT_PI) /* ( 2V/pi)^{d/4} */ + 0.25 *logdetU /* Sx ^1/4 */ - s->invscale * hSxh /* exp(-V(U-x) S (U-x)) */ + CovList[next->nr].logmixweight(x, next, s)/* g*/ + s->logInvSqrtDens; /* 1 / sqrt(f) */ if (!(exponent < 5.0) && PL > 4) { if (!(exponent < 6.0)) // could be NA, too PRINTF("\n%f logDetU=%f %f lgmx=%f %f alph=%f z=%f", 0.25 * dim * (2.0 + s->loginvscale - 2*M_LN_PId2) /* 2 V/pi)^{d/2} */ , 0.25 * logdetU /* Sx ^1/4 */ , -s->invscale * hSxh /* exp(-V(U-x) S (U-x)) */ , CovList[next->nr].logmixweight(x, next, s)/* g*/ , s->logInvSqrtDens, s->c[DRAWMIX_ALPHA] , exponent); else PRINTF("!"); } assert(exp(exponent) < 10000000.0); if (false) if ( s->c[MPP_VV] + s->c[MPP_SPECTRAL] * xi > 100000) { printf("%f %e xi=%f %e %f\n",// s->c[MPP_VV], s->c[MPP_SPECTRAL], xi, s->c[MPP_SPECTRAL] * xi, cos(s->c[MPP_VV] + s->c[MPP_SPECTRAL] * xi)); //assert(s->c[MPP_VV] + s->c[MPP_SPECTRAL] * xi < 100000); } if (false) printf("%e %e %e %e\n",// (exponent), exp(exponent), s->c[MPP_VV] + s->c[MPP_SPECTRAL] * xi, cos(s->c[MPP_VV] + s->c[MPP_SPECTRAL] * xi)); free(Sx); return (res_type) (exp(exponent) * cos(s->c[MPP_VV] + s->c[MPP_SPECTRAL] * xi)); /* Y */ } /* Whittle-Matern or Whittle or Besset */ void kappa_rational(int i, cov_model *cov, int *nr, int *nc){ *nc = (i == 0) ? cov->tsdim : 1; *nr = (i==0) ? cov->tsdim : (i==1) ? 2 : -1; } double minEigenrational(cov_model *cov) { double *a = cov->p[1]; 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 = cov->p[0], *a = cov->p[1]; nu = 0.0; for (k=0, i=0; inrow[1] == 1) { double dummy = cov->p[1][0]; free(cov->p[1]); cov->p[1] = (double *) malloc(sizeof(double) * 2); cov->p[1][0] = dummy; cov->p[1][1] = 0.0; cov->nrow[1] = 2; } return NOERROR; } void rangerational(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges + 0; range->min[0] = RF_NEGINF; range->max[0] = RF_INF; range->pmin[0] = -1e10; range->pmax[0] = 1e10; range->openmin[0] = true; range->openmax[0] = true; range->min[1] = 0.0; range->max[1] = RF_INF; range->pmin[1] = 0.0; range->pmax[1] = 10; range->openmin[1] = false; range->openmax[1] = true; } // Sigma(x) = diag>0 + A'xx'A void kappa_EAxxA(int i, cov_model *cov, int *nr, int *nc){ *nc = (i == 1) ? cov->tsdim : 1; *nr = (i <= 1) ? cov->tsdim : -1; } void EAxxA(double *x, cov_model *cov, double *v) { int d, k, j, dim = cov->tsdim; double xA[EaxxaMaxDim], *E = cov->p[0], *A = cov->p[1]; for (k=0, d=0; dp[0]; int i, dim = cov->tsdim; for (min = RF_INF, i=0; ipref, pref, sizeof(pref_type)); if (cov->xdim > EaxxaMaxDim) { sprintf(ERRORSTRING, "For technical reasons max. dimension for ave is %d. Got %d.", EaxxaMaxDim, cov->xdim); return ERRORMSG; } cov->vdim = cov->tsdim; return NOERROR; } void rangeEAxxA(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges + 0; range->min[0] = 0.0; range->max[0] = RF_INF; range->pmin[0] = 0.0001; range->pmax[0] = 10; range->openmin[0] = true; range->openmax[0] = true; range->min[1] = RF_NEGINF; range->max[1] = RF_INF; range->pmin[1] = -1e10; range->pmax[1] = 1e10; range->openmin[1] = true; range->openmax[1] = true; } // Sigma(x) = diag>0 + A'xx'A void kappa_EtAxxA(int i, cov_model *cov, int *nr, int *nc){ *nc = (i == 1) ? cov->tsdim : 1; *nr = (i <= 1) ? cov->tsdim : (i==2) ? 1 : -1; } void EtAxxA(double *x, cov_model *cov, double *v) { int d, k, j, dim = cov->tsdim, time = dim - 1; double xDR[EaxxaMaxDim], *E = cov->p[0], *D = cov->p[1], phi = cov->p[2][0], c = cos(phi * x[time]), s = sin(phi * x[time]), R[9]; assert(dim ==3); // PrintModelInfo(cov); 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 xD[EaxxaMaxDim]; for (k=0, d=0; dp[0]; int i, dim = cov->tsdim; for (min = RF_INF, i=0; ipref, pref, sizeof(pref_type)); cov->vdim = cov->tsdim; return NOERROR; } void rangeEtAxxA(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges + 0; int i; range->min[0] = 0.0; range->max[0] = RF_INF; range->pmin[0] = 0.0001; range->pmax[0] = 10; range->openmin[0] = true; range->openmax[0] = true; for (i=1; 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 <= 1) ? 1 : -1; } void rotat(double *x, cov_model *cov, double *v) { int dim = cov->tsdim, time = dim - 1; double speed = cov->p[0][0], phi = cov->p[0][1], 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; // printf("%f\n", *v); } double minEigenrotat(cov_model *cov) { return 0.0; } int checkrotat(cov_model *cov){ // if (cov->tsdim != 3) ERR("only 3-d allowed for rotat!"); // pref_type pref = // {5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 5}; // CE CO CI TBM23 Sp di sq Ma av n mpp Hy any // memcpy(cov->pref, pref, sizeof(pref_type)); cov->vdim = cov->tsdim - 1; return NOERROR; } void rangerotat(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges + 0; 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 == 0) ? 1 : -1; } void Rotat(double *x, cov_model *cov, double *v) { int d, k, j, dim = cov->tsdim, time = dim - 1; double phi = cov->p[0][0], 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; dpref, pref, sizeof(pref_type)); cov->vdim = cov->tsdim; return NOERROR; } void rangeRotat(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges + 0; range->min[0] = RF_NEGINF; range->max[0] = RF_INF; range->pmin[0] = -1e10; range->pmax[0] = 1e10; range->openmin[0] = true; range->openmax[0] = true; } /* Whittle-Matern or Whittle or Besset */ // statt 0 Parameter: 2 Parameter, M und z fuer xi void kappaNonStWM(int i, cov_model *cov, int *nr, int *nc){ *nc = 1; *nr = (i==0) ? 1 : -1; } void NonStWMQ(double *x, double *y, double sqrtQ, cov_model *cov, double *v){ // check calling functions, like hyperbolic and gneiting if any changings !! double loggamma, nuxy, nux, nuy; cov_model *nu = cov->sub[0]; if (nu == NULL) { nuxy = cov->p[0][0]; loggamma = lgammafn(nuxy); } else { covfct Cnu = CovList[nu->nr].cov; Cnu(x, nu, &nux); Cnu(y, nu, &nuy); nuxy = 0.5 * (nux + nuy); loggamma = 0.5 * (lgammafn(nux) + lgammafn(nuy)); } if (sqrtQ == 0.0) { *v = 1.0; return; } *v = 2.0 * exp(nuxy * log(0.5 * sqrtQ) - loggamma + log(bessel_k(sqrtQ, nuxy, 2.0)) - sqrtQ); } void NonStWM(double *x, double *y, cov_model *cov, double *v){ // check calling functions, like hyperbolic and gneiting if any changings !! int d, dim = cov->tsdim; double Q=0.0; for (d=0; dsub[0]; // *Q=cov->sub[1]; int err, dim = cov->tsdim; cov->manipulating_x=true; if (cov->p[0] == NULL) { if (nu == NULL) error("nu is missing"); cov->p[0] = (double*) malloc(sizeof(double)); cov->p[0][0] = 1.0; // never used, but avoids errors in checks cov->nrow[0] = cov->ncol[0] = 1; } if ((err = checkkappas(cov)) != NOERROR) return err; if (nu != NULL) { if ((err = check2X(nu, dim, dim, AUXMATRIX, ANISOTROPIC, UNIVARIATE)) != NOERROR) return err; if (nu->sub[0]->tsdim != cov->tsdim) ERR("submodel not allowed"); } return NOERROR; } void rangeNonStWM(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges; range->min[0] = 0.0; range->max[0] = RF_INF; range->pmin[0] = 1e-2; range->pmax[0] = 10.0; range->openmin[0] = true; range->openmax[0] = true; } // using nu^(-1-nu+a)/2 for g and v^-a e^{-1/4v} as density instead of frechet // the bound 1/3 can be dropped static double eM025 = exp(-0.25); double DrawLogMixNonStWM(cov_model *cov, mpp_storage *s) { // inv scale // V ~ F in stp cov_model *nu = cov->sub[0]; double minnu = (nu == NULL) ? cov->p[0][0] : CovList[nu->nr].mineigenvalue(nu), alpha = 1.0 + 0.5 /* 0< . < 1*/ * (3.0 * minnu - 2.0 * s->c[DRAWMIX_EXPONENT]); if (alpha > 2.0) alpha = 2.0; // original choice if (alpha <= 1.0) ERR("minimual nu too low or dimension too high"); s->c[DRAWMIX_ALPHA] = alpha; double beta = s->c[DRAWMIX_BETA], p = s->c[DRAWMIX_P], logU; if (UNIFORM_RANDOM < p){ s->c[DRAWMIX_ALPHA] = beta; logU = log(UNIFORM_RANDOM * eM025); s->c[DRAWMIX_FACTOR] = -0.5 * log(0.25 * p * (beta - 1.0)) + 0.25; } else { s->c[DRAWMIX_ALPHA] = alpha; logU = log(eM025 + UNIFORM_RANDOM * (1.0 - eM025)); s->c[DRAWMIX_FACTOR] = -0.5 * log(0.25 * (1.0 - p) * (alpha - 1.0)); } return log( -0.25 / logU) / (s->c[DRAWMIX_ALPHA] - 1.0); //=invscale } double LogMixWeightNonStWM(double *x, cov_model *cov, mpp_storage *s) { // g(v,x) in stp double nu, alpha = s->c[DRAWMIX_ALPHA], loginvscale = s->loginvscale; cov_model *Nu = cov->sub[0]; static double storage = 0.0; if (Nu == NULL) nu = cov->p[0][0]; else CovList[Nu->nr].cov(x, Nu, &nu); double z; z = - nu * M_LN2 // in g0 // eine 2 kuerzt sich raus + 0.5 * ((1.0 - nu) /*in g0*/ + alpha /*lambda*/ - 2.0 /*fre*/) * loginvscale - 0.5 * lgammafn(nu) // in g0 + s->c[DRAWMIX_FACTOR] // lambda - 0.125 / s->invscale // g: Frechet + 0.125 * pow(s->invscale, 1.0 - alpha); // lambda: frechet if (!(z < 7.0)) { if (storage != loginvscale) { if (PL > 4) PRINTF("alpha=%f, is=%f, cnst=%f logi=%f lgam=%f loga=%f invlogs=%f pow=%f z=%f\n", alpha,s->invscale, (1.0 - nu) * M_LN2 , + ((1.0 - nu) * 0.5 + alpha - 2.0) * loginvscale ,- 0.5 * lgammafn(nu) , -s->c[DRAWMIX_FACTOR] ,- 0.25 / s->invscale , + 0.25 * pow(s->invscale, - alpha) , z); storage = loginvscale; } //assert(z < 10.0); } return z; } /* nsst */ /* Tilmann Gneiting's space time models, part I */ void nsst(double *x, cov_model *cov, double *v) { cov_model *next1 = cov->sub[0]; cov_model *next2 = cov->sub[1]; cov_fct *C1 = CovList + next1->nr, *C2 = CovList + next2->nr; double v1, v2, psi, phi, y; C2->cov(ZERO, next2, &v1); C2->cov(x + 1, next2, &v2); psi = sqrt(1.0 + v1 - v2); // C0 : C(0) oder 0 // Cx : C(x) oder -gamma(x) // printf("%f %f v=%f %f %f p=%f \n", x[0],x[1], v1, v2, psi, cov->p[0][0]); y = x[0] / psi; C1->cov(&y, next1, &phi); *v = pow(psi, -cov->p[0][0]) * phi; //printf("%f %f;%f %f %f : %f\n", x[0], x[1], phi, psi, cov->p[0][0], *v); } void TBM2nsst(double *x, cov_model *cov, double *v) { cov_model *next1 = cov->sub[0]; cov_model *next2 = cov->sub[1]; cov_fct *C1 = CovList + next1->nr, *C2 = CovList + next2->nr; double v1, v2, psi, phi, y; C2->cov(ZERO, next2, &v1); C2->cov(x + 1, next2, &v2); psi = 1.0 + v1 - v2; // C0 : C(0) oder 0 // Cx : C(x) oder -gamma(x) y = x[0] / psi; C1->tbm2(&y, next1, &phi); *v = pow(psi, -cov->p[0][0]) * phi; } void Dnsst(double *x, cov_model *cov, double *v) { cov_model *next1 = cov->sub[0]; cov_model *next2 = cov->sub[1]; cov_fct *C1 = CovList + next1->nr, *C2 = CovList + next2->nr; double v1, v2, psi, phi, y; C2->cov(ZERO, next2, &v1); C2->cov(x + 1, next2, &v2); psi = 1.0 + v1 - v2; // C0 : C(0) oder 0 // Cx : C(x) oder -gamma(x) y = x[0] / psi; C1->D(&y, next1, &phi); *v = pow(psi, -cov->p[0][0] - 1) * phi; } int checknsst(cov_model *cov) { cov_model *next1 = cov->sub[0]; cov_model *next2 = cov->sub[1]; int err; cov->manipulating_x=true; if (cov->xdim != 2) { sprintf(ERRORSTRING, "%s", "reduced dimension must be 2"); return ERRORM; } if ((err = checkkappas(cov)) != NOERROR) return err; cov->normalmix = cov->finiterange = false; next1->xdim = 1; if ((err = check2X(next1, cov->tsdim, 1, STATIONARY, ISOTROPIC, UNIVARIATE)) != NOERROR) return err; if (!next1->normalmix) XERR(ERRORNORMALMIXTURE); setbackward(cov, next1); cov->normalmix = false; next2->tsdim = next2->xdim = 1; if ((err = check2X(next2, 1, 1, VARIOGRAM, ISOTROPIC, UNIVARIATE)) != NOERROR) return err; // kein setbackward(cov, next2); return NOERROR; } void rangensst(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges; range->min[0] = cov->tsdim - 1; range->max[0] = RF_INF; range->pmin[0] = cov->tsdim - 1; range->pmax[0] = 10.0; range->openmin[0] = false; range->openmax[0] = true; }