/* Authors Martin Schlather, schlather@math.uni-mannheim.de Definition of correlation functions and derivatives (spectral measures, tbm operators) Note: * 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 are not used here * definitions for the random coin method can be found in MPPFcts.cc * definitions for genuinely anisotropic or nondomain models are in SophisticatedModel.cc; hyper models also in Hypermodel.cc Copyright (C) 2001 -- 2003 Martin Schlather Copyright (C) 2004 -- 2004 Yindeng Jiang & Martin Schlather Copyright (C) 2005 -- 2014 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 "RF.h" #include "primitive.h" #include #include // {min, max} x {theor, pract} x length(param) //static double *range_stable[4] = {0, 2, 0.06, 2}; //double *range_whittle[4]= {0, RF_INF, 1e-2, 10.0}; //double *range_cauchy[4] = {0, RF_INF, 0.09, 10.0}; //static double *range_genCauchy[8] = {0, 2, 0.05, 2, // 0, RF_INF, 0.05, 10.0}; #define i11 0 #define i21 1 #define i22 2 #define epsilon 1e-15 double BesselUpperB[Nothing + 1] = {80, 80, 80, // circulant 80, R_PosInf, // TBM 80, 80, // direct & sequ NA_REAL, NA_REAL, NA_REAL, // GMRF, ave, nugget NA_REAL, NA_REAL, NA_REAL, // exotic R_PosInf // Nothing }; double interpolate(double y, double *stuetz, int nstuetz, int origin, double lambda, int delta) { int index,minindex,maxindex,i; double weights,sum,diff,a; index = origin + (int) y; minindex = index - delta; if (minindex<0) minindex=0; maxindex = index + 1 + delta; if (maxindex>nstuetz) maxindex=nstuetz; weights = sum = 0.0; for (i=minindex;i BCW_EPS) *v = BCW_CAUCHY / (1.0 - pow(2.0, zeta)); else { double dewijs = log(1.0 + pow(*x, alpha)), zetadewijs = zeta * dewijs, zetalog2 = zeta * LOG2 ; if (fabs(zetadewijs) > BCW_EPS) *v = BCW_CAUCHY / (zeta * BCW_TAYLOR_ZETA); else { *v = dewijs * (1.0 + 0.5 * zetadewijs * (1.0 + ONETHIRD *zetadewijs)) / BCW_TAYLOR_ZETA; // printf("x=%f v=%f %f dewijs %f %f %f\n", *x, *v, pow(*x, alpha), alpha, dewijs, zeta, BCW_TAYLOR_ZETA); } // printf("x=%f %f %f dewijs %f %f %f\n", *x, pow(*x, alpha), alpha, dewijs, zeta, BCW_TAYLOR_ZETA); } } void Dbcw(double *x, cov_model *cov, double *v){ double ha, alpha = P0(BCW_ALPHA), beta=P0(BCW_BETA), zeta=beta / alpha, absZeta = fabs(zeta), y=*x; if (y ==0.0) { *v = ((alpha > 1.0) ? 0.0 : (alpha < 1.0) ? -INFTY : alpha); } else { ha=pow(y, alpha - 1.0); *v = alpha * ha * pow(1.0 + ha * y, zeta - 1.0); } if (absZeta > BCW_EPS) *v *= zeta / (1.0 - pow(2.0, zeta)); else { double zetalog2 = zeta * LOG2; *v /= BCW_TAYLOR_ZETA; } } void DDbcw(double *x, cov_model *cov, double *v){ double ha, alpha = P0(BCW_ALPHA), beta=P0(BCW_BETA), zeta = beta / alpha, absZeta = fabs(zeta), y=*x; if (y == 0.0) { *v = ((alpha==2.0) ? -beta * (1.0 - beta) : INFTY); } else { ha = pow(y, alpha); *v = -alpha * ha / (y * y) * (1.0 - alpha + (1.0 - beta) * ha) * pow(1.0 + ha, beta / alpha - 2.0); } if (absZeta > BCW_EPS) *v *= zeta / (1.0 - pow(2.0, zeta)); else { double zetalog2 = zeta * LOG2; *v /= BCW_TAYLOR_ZETA; } } void Inversebcw(double *x, cov_model *cov, double *v) { // printf("inverse bcw\n"); double alpha = P0(BCW_ALPHA), beta=P0(BCW_BETA), zeta = beta / alpha; if (*x == 0.0) { *v = beta < 0.0 ? RF_INF : 0.0; return; } if (zeta != 0.0) *v = pow(pow(*x * fabs(pow(2.0, zeta) - 1.0) + 1.0, 1.0/zeta) - 1.0, 1.0/alpha); else *v = pow(exp(*x * LOG2) - 1.0, 1.0 / alpha); } int checkbcw(cov_model *cov) { double alpha = P0(BCW_ALPHA), beta=P0(BCW_BETA); //double alpha = P0(BCW_ALPHA); if (cov->tsdim > 2) cov->pref[CircEmbedCutoff] = cov->pref[CircEmbedIntrinsic] = PREF_NONE; cov->logspeed = beta > 0 ? RF_INF : beta < 0.0 ? 0 : alpha * INVLOG2; return NOERROR; } bool Typebcw(Types required, cov_model *cov) { double beta=P0(BCW_BETA); if ((required==PosDefType && beta < 0.0) || required==NegDefType || required==ShapeType) return true; if (PisNULL(BCW_ALPHA) || !ISNAN(P0(BCW_ALPHA)) || cov->kappasub[BCW_ALPHA]!=NULL) return false; return P0(BCW_ALPHA) <= 1.0 && required==TcfType && beta < 0.0; } void rangebcw(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range) { range->min[BCW_ALPHA] = 0.0; range->max[BCW_ALPHA] = 2.0; range->pmin[BCW_ALPHA] = 0.05; range->pmax[BCW_ALPHA] = 2.0; range->openmin[BCW_ALPHA] = true; range->openmax[BCW_ALPHA] = false; range->min[BCW_BETA] = RF_NEGINF; range->max[BCW_BETA] = 2.0; range->pmin[BCW_BETA] = -10.0; range->pmax[BCW_BETA] = 2.0; range->openmin[BCW_BETA] = true; range->openmax[BCW_BETA] = false; } void coinitbcw(cov_model *cov, localinfotype *li) { double //alpha = P0(BCW_ALPHA), beta=P0(BCW_BETA); if (beta < 0) coinitgenCauchy(cov, li); else { li->instances = 0; } } void ieinitbcw(cov_model *cov, localinfotype *li) { if (P0(BCW_BETA) < 0) ieinitgenCauchy(cov, li); else { ieinitBrownian(cov, li); // to do: can nicht passen!! // todo: nachrechnen, dass OK! } } #define LOW_BESSELJ 1e-20 #define LOW_BESSELK 1e-20 #define BESSEL_NU 0 void Bessel(double *x, cov_model *cov, double *v){ static double nuOld=RF_INF; static double gamma; double nu = P0(BESSEL_NU), y=*x; if (y <= LOW_BESSELJ) {*v = 1.0; return;} if (y == RF_INF) {*v = 0.0; return;} // also for cosine i.e. nu=-1/2 if (nuOld!=nu) { nuOld=nu; gamma = gammafn(nuOld+1.0); } *v = gamma * pow(2.0 / y, nuOld) * bessel_j(y, nuOld); } int initBessel(cov_model *cov, storage VARIABLE_IS_NOT_USED *s) { ASSERT_GAUSS_METHOD(SpectralTBM); return NOERROR; } int checkBessel(cov_model *cov) { // Whenever TBM3Bessel exists, add further check against too small nu! double nu = P0(BESSEL_NU); int i; double dim = (2.0 * P0(BESSEL_NU) + 2.0); for (i=0; i<= Nothing; i++) cov->pref[i] *= (ISNAN(nu) || nu < BesselUpperB[i]); if (cov->tsdim>2) cov->pref[SpectralTBM] = PREF_NONE; // do to d > 2 ! cov->maxdim = (ISNAN(dim) || dim >= INFDIM) ? INFDIM : (int) dim; return NOERROR; } void spectralBessel(cov_model *cov, storage *S, double *e) { spectral_storage *s = &(S->Sspectral); double nu = P0(BESSEL_NU); /* see Yaglom ! */ // nu==0.0 ? 1.0 : // not allowed anymore; // other wise densityBessel (to define) will not work if (nu >= 0.0) { E12(s, cov->tsdim, nu > 0 ? sqrt(1.0 - pow(UNIFORM_RANDOM, 1 / nu)) : 1, e); } else { double A; assert(cov->tsdim == 1); if (nu == -0.5) A = 1.0; else { // siehe private/bessel.pdf, p. 6, Remarks // http://homepage.tudelft.nl/11r49/documents/wi4006/bessel.pdf while (true) { A = 1.0 - pow(UNIFORM_RANDOM, 1.0 / ( P0(BESSEL_NU) + 0.5)); if (UNIFORM_RANDOM <= pow(1 + A, nu - 0.5)) break; } } E1(s, A, e); } } void rangeBessel(cov_model *cov, range_type *range){ range->min[BESSEL_NU] = 0.5 * ((double) cov->tsdim - 2.0); range->max[BESSEL_NU] = RF_INF; range->pmin[BESSEL_NU] = 0.0001 + range->min[BESSEL_NU]; range->pmax[BESSEL_NU] = range->pmin[BESSEL_NU] + 10.0; range->openmin[BESSEL_NU] = false; range->openmax[BESSEL_NU] = true; } /* Cauchy models */ #define CAUCHY_GAMMA 0 void Cauchy(double *x, cov_model *cov, double *v){ double gamma = P0(CAUCHY_GAMMA); *v = pow(1.0 + *x * *x, -gamma); } void logCauchy(double *x, cov_model *cov, double *v, double *sign){ double gamma = P0(CAUCHY_GAMMA); *v = log(1.0 + *x * *x) * -gamma; *sign = 1.0; } void TBM2Cauchy(double *x, cov_model *cov, double *v){ double gamma = P0(CAUCHY_GAMMA), y2, lpy2; y2 = *x * *x; lpy2 = 1.0 + y2; switch ((int) (gamma * 2.0 + 0.001)) {// ueber check sichergestellt case 1 : *v = 1.0 / lpy2; break; case 3 : *v = (1.0 - y2)/ (lpy2 * lpy2); break; case 5 : *v = (1.0-y2*(2.0+0.333333333333333333333*y2))/(lpy2*lpy2*lpy2); break; case 7 : lpy2 *= lpy2; *v = (1.0- y2*(3.0+y2*(1.0+0.2*y2)))/(lpy2 * lpy2); break; default : ERR("TBM2 for cauchy only possible for alpha=0.5 + k; k=0, 1, 2, 3 "); } } void DCauchy(double *x, cov_model *cov, double *v){ double y=*x, gamma = P0(CAUCHY_GAMMA); *v = (-2.0 * gamma * y) * pow(1.0 + y * y, -gamma - 1.0); } void DDCauchy(double *x, cov_model *cov, double *v){ double ha = *x * *x, gamma = P0(CAUCHY_GAMMA); *v = 2.0 * gamma * ((2.0 * gamma + 1.0) * ha - 1.0) * pow(1.0 + ha, -gamma - 2.0); } void InverseCauchy(double*x, cov_model *cov, double *v){ double gamma = P0(CAUCHY_GAMMA); if (*x == 0.0) *v = RF_INF; else *v = sqrt(pow(*x, -1.0 / gamma) - 1.0); } int checkCauchy(cov_model VARIABLE_IS_NOT_USED *cov){ // double gamma = P0(CAUCHY_GAMMA); // if (gamma != 0.5 && gamma != 1.5 && gamma != 2.5 && gamma != 3.5) // cov->pref[TBM2] = PREF_NONE; return NOERROR; } void rangeCauchy(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[CAUCHY_GAMMA] = 0.0; range->max[CAUCHY_GAMMA] = RF_INF; range->pmin[CAUCHY_GAMMA] = 0.09; range->pmax[CAUCHY_GAMMA] = 10.0; range->openmin[CAUCHY_GAMMA] = true; range->openmax[CAUCHY_GAMMA] = true; } void coinitCauchy(cov_model VARIABLE_IS_NOT_USED *cov, localinfotype *li) { li->instances = 1; li->value[0] = 1.0; // q[CUTOFF_A] li->msg[0] = MSGLOCAL_JUSTTRY; } void DrawMixCauchy(cov_model VARIABLE_IS_NOT_USED *cov, double *random) { //better GR 3.381.4 ?? !!!! // split into parts <1 and >1 ?> *random = -log(1.0 -UNIFORM_RANDOM); } double LogMixDensCauchy(double VARIABLE_IS_NOT_USED *x, double logV, cov_model *cov) { double gamma = P0(CAUCHY_GAMMA); // da dort 1/w vorgezogen return 0.5 * (gamma - 1.0) * logV - 0.5 * lgammafn(gamma); } /* another Cauchy model */ #define CTBM_ALPHA 0 #define CTBM_BETA 1 #define CTBM_GAMMA 2 void Cauchytbm(double *x, cov_model *cov, double *v){ double ha, alpha = P0(CTBM_ALPHA), beta = P0(CTBM_BETA), gamma = P0(CTBM_GAMMA), y=*x; if (y==0) { *v = 1.0; } else { ha=pow(y, alpha); *v = (1.0 + (1.0 - beta / gamma) * ha) * pow(1.0 + ha, -beta / alpha - 1.0); } } //void TBM3Cauchytbm(double *x, cov_model *cov, double *v){ // double ha, bg, a = P(CTBM_ALPHA), b = P(CTBM_BETA), c = P(CTBM_GAMMA); // ha=pow(*x, a); // bg=b / c;// *v = // (1 + ha * (1 - bg * (1 + a) + (1 - b) * (1 + (1 - bg) * ha))) * // pow(1 + ha, -b / a - 2.0); //} void DCauchytbm(double *x, cov_model *cov, double *v){ double y= *x, ha, alpha = P0(CTBM_ALPHA), beta = P0(CTBM_BETA), gamma = P0(CTBM_GAMMA); if (y == 0.0) *v = 0.0; // WRONG VALUE, but multiplied else { // by zero anyway ha = pow(y, alpha - 1.0); *v = beta * ha * (-1.0 - alpha / gamma + ha * y * (beta / gamma - 1.0)) * pow(1.0 + ha * y, -beta /alpha - 2.0); } } void rangeCauchytbm(cov_model *cov, range_type *range){ range->min[CTBM_ALPHA] = 0.0; range->max[CTBM_ALPHA] = 2.0; range->pmin[CTBM_ALPHA] = 0.05; range->pmax[CTBM_ALPHA] = 2.0; range->openmin[CTBM_ALPHA] = true; range->openmax[CTBM_ALPHA] = false; range->min[CTBM_BETA] = 0.0; range->max[CTBM_BETA] = RF_INF; range->pmin[CTBM_BETA] = 0.05; range->pmax[CTBM_BETA] = 10.0; range->openmin[CTBM_BETA] = true; range->openmax[CTBM_BETA] = true; range->min[CTBM_GAMMA] = (double) cov->tsdim; range->max[CTBM_GAMMA] = RF_INF; range->pmin[CTBM_GAMMA] = range->min[CTBM_GAMMA]; range->pmax[CTBM_GAMMA] = range->pmin[CTBM_GAMMA] + 10.0; range->openmin[CTBM_GAMMA] = false; range->openmax[CTBM_GAMMA] = true; } /* circular model */ void circular(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v) { double y = *x; *v = (y >= 1.0) ? 0.0 : 1.0 - (2.0 * (y * sqrt(1.0 - y * y) + asin(y))) * INVPI; } void Dcircular(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v){ double y = *x * *x; *v = (y >= 1.0) ? 0.0 : -4 * INVPI * sqrt(1.0 - y); } int structCircSph(cov_model *cov, cov_model **newmodel, int dim) { ASSERT_NEWMODEL_NOT_NULL; switch (cov->role) { //case ROLE_SMITH : case ROLE_POISSON_GAUSS : { addModel(newmodel, BALL); addModel(newmodel, DOLLAR); addModel((*newmodel)->kappasub + DSCALE, SCALESPHERICAL); kdefault((*newmodel)->kappasub[DSCALE], SPHERIC_SPACEDIM, (double) cov->tsdim); kdefault((*newmodel)->kappasub[DSCALE], SPHERIC_BALLDIM, (double) dim); } break; case ROLE_POISSON : return addUnifModel(cov, 1.0, newmodel); // to do: felix //PMI(cov->calling->calling); case ROLE_MAXSTABLE : return addUnifModel(cov, 1.0, newmodel); //PMI(cov->calling->calling); default: SERR1("ball currently only allowed for role 'Gauss' and 'Smith' Got %s.", ROLENAMES[cov->role]); } return NOERROR; } int structcircular(cov_model *cov, cov_model **newmodel) { return structCircSph(cov, newmodel, 2); } // constant (matrix); void constant(double VARIABLE_IS_NOT_USED *x, cov_model *cov, double *v){ location_type *loc = Loc(cov); listoftype *list= PLIST(CONSTANT_M); int i,j, // *ncol = list->ncol, element = P0INT(CONSTANT_ELMNT), *nrow = list->nrow; // anzahl listen elemente int vdim = cov->vdim2[0], lx = nrow[element] / vdim, //nrow = #pts * vdim ly = nrow[element] * lx; assert(cov->vdim2[0] == cov->vdim2[1]); double **p = list->p, *X = (p[element] + loc->i_row + loc->i_col * nrow[element]), *Y=X, *w = v; if (loc->i_row >= lx || loc->i_col >= lx) { PRINTF("size=%d current indices=(%d, %d)\n", lx, loc->i_row, loc->i_col); // crash(cov); ERR("constant model: indices out of range"); } if (element >= cov->nrow[CONSTANT_M]) ERR("constant model: list index out of range"); for (i=0; ip[element]; int n = M->nrow[element] * M->ncol[element]; memcpy(v, p, n * sizeof(double)); loc_set(cov, M->nrow[element]); // printf("const %d\n", cov->totalpoints); } char iscovmatrix_constant(cov_model VARIABLE_IS_NOT_USED *cov) { return 2; } int checkconstant(cov_model *cov) { listoftype *list = PLIST(CONSTANT_M); int info, err, total, i, vdim, totpts, m = cov->nrow[CONSTANT_M], *q, *ncol = list->ncol, *nrow = list->nrow; // anzahl listen elemente double *dummy, **p = list->p; if (cov->q != NULL) { cov->vdim2[0] = cov->vdim2[1] = P0INT(CONSTANT_VDIM); return ((int*) cov->q)[0]; } else cov->q = (double*) MALLOC(sizeof(int)); q = ((int*) cov->q); q[0] = NOERROR; if ((err = checkkappas(cov, false)) != NOERROR) return err; kdefault(cov, CONSTANT_ELMNT, 0); kdefault(cov, CONSTANT_VDIM, 1); // vdim ! cov->vdim2[0] = cov->vdim2[1] = vdim = P0INT(CONSTANT_VDIM); if (vdim > 1) return q[0] = ERRORVDIMNOTPROGRAMMEDYET; // frag ist hier in welcher Reihenfolde die multivariaten und raeumlichen // korrelationen abfolgen, siehe vario** fuer die 2 Moeglichkeiten for (i=0; inrow[i] == 0) { return q[0] = ERROR_MATRIX_SQUARE; } totpts = nrow[i] / vdim; if (totpts * vdim != nrow[i]) { return q[0] = ERROR_MATRIX_VDIM; } // check whether positive eigenvalue total = nrow[i] * ncol[i] * sizeof(double); // NICHT weiter vorne dummy = (double*) MALLOC(total); MEMCOPY(dummy, p[i], total); if (false) { printf("in Primitive.cc; constant\n"); // int k, l, mm; for (mm=k=0; kmatrix_indep_of_x = true; cov->mpp.maxheights[0] = RF_NA; err = checkkappas(cov); return err; } void rangeconstant(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[CONSTANT_ELMNT] = 0; range->max[CONSTANT_ELMNT] = MAXELEMENTS; range->pmin[CONSTANT_ELMNT] = 0; range->pmax[CONSTANT_ELMNT] = MAXELEMENTS; range->openmin[CONSTANT_ELMNT] = false; range->openmax[CONSTANT_ELMNT] = false; range->min[CONSTANT_M] = RF_NEGINF; range->max[CONSTANT_M] = RF_INF; range->pmin[CONSTANT_M] = -1e10; range->pmax[CONSTANT_M] = 1e10; range->openmin[CONSTANT_M] = true; range->openmax[CONSTANT_M] = true; range->min[CONSTANT_VDIM] = 1; range->max[CONSTANT_VDIM] = 9999; range->pmin[CONSTANT_VDIM] = 1; range->pmax[CONSTANT_VDIM] = 9999; range->openmin[CONSTANT_VDIM] = false; range->openmax[CONSTANT_VDIM] = false; } /* coxgauss, cmp with nsst1 !! */ // see Gneiting.cc /* cubic */ void cubic(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v) { double y=*x, y2=y * y; *v = (y >= 1.0) ? 0.0 : (1.0 + (((0.75 * y2 - 3.5) * y2 + 8.75) * y - 7) * y2); } void Dcubic(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v) { double y=*x, y2=y * y; *v = (y >= 1.0) ? 0.0 : y * (-14.0 + y * (26.25 + y2 * (-17.5 + 5.25 * y2))); } /* cutoff */ // see operator.cc /* dagum */ #define DAGUM_BETA 0 #define DAGUM_GAMMA 1 void dagum(double *x, cov_model *cov, double *v){ double gamma = P0(DAGUM_GAMMA), beta=P0(DAGUM_BETA); *v = 1.0 - pow((1 + pow(*x, -beta)), -gamma/beta); } void Inversedagum(double *x, cov_model *cov, double *v){ double gamma = P0(DAGUM_GAMMA), beta=P0(DAGUM_BETA); *v = *x == 0.0 ? RF_INF : pow(pow(1.0 - *x, - beta / gamma ) - 1.0, 1.0 / beta); } void Ddagum(double *x, cov_model *cov, double *v){ double y=*x, xd, gamma = P0(DAGUM_GAMMA), beta=P0(DAGUM_BETA); xd = pow(y, -beta); *v = -gamma * xd / y * pow(1 + xd, -gamma/ beta -1); } void rangedagum(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[DAGUM_BETA] = 0.0; range->max[DAGUM_BETA] = 1.0; range->pmin[DAGUM_BETA] = 0.01; range->pmax[DAGUM_BETA] = 1.0; range->openmin[DAGUM_BETA] = true; range->openmax[DAGUM_BETA] = false; range->min[DAGUM_GAMMA] = 0.0; range->max[DAGUM_GAMMA] = 1.0; range->pmin[DAGUM_GAMMA] = 0.01; range->pmax[DAGUM_GAMMA] = 1.0; range->openmin[DAGUM_GAMMA] = true; range->openmax[DAGUM_GAMMA] = true; } /* damped cosine -- derivative of e xponential:*/ #define DC_LAMBDA 0 void dampedcosine(double *x, cov_model *cov, double *v){ double y = *x, lambda = P0(DC_LAMBDA); *v = (y == RF_INF) ? 0.0 : exp(-y * lambda) * cos(y); } void logdampedcosine(double *x, cov_model *cov, double *v, double *sign){ double y = *x, lambda = P0(DC_LAMBDA); if (y==RF_INF) { *v = - RF_INF; *sign = 0.0; } else { double cosy=cos(y); *v = -y * lambda + log(fabs(cosy)); *sign = cosy > 0.0 ? 1.0 : cosy < 0.0 ? -1.0 : 0.0; } } void Inversedampedcosine(double *x, cov_model *cov, double *v){ Inverseexponential(x, cov, v); } void Ddampedcosine(double *x, cov_model *cov, double *v){ double y = *x, lambda = P0(DC_LAMBDA); *v = - exp(-lambda*y) * (lambda * cos(y) + sin(y)); } int checkdampedcosine(cov_model *cov){ cov->maxdim = ISNAN(P0(DC_LAMBDA)) ? INFDIM : (int) (PIHALF / atan(1.0 / P0(DC_LAMBDA))); // print("%d %f \n", cov->maxdim, (PIHALF / atan(1.0 / P0(DC_LAMBDA)))); return NOERROR; } void rangedampedcosine(cov_model *cov, range_type *range){ range->min[DC_LAMBDA] = 1.0 / tan(PIHALF / cov->tsdim); range->max[DC_LAMBDA] = RF_INF; range->pmin[DC_LAMBDA] = range->min[DC_LAMBDA] + 1e-10; range->pmax[DC_LAMBDA] = 10; range->openmin[DC_LAMBDA] = false; range->openmax[DC_LAMBDA] = true; } /* De Wijsian */ #define DEW_ALPHA 0 // for both dewijsian models void dewijsian(double *x, cov_model *cov, double *v){ double alpha = P0(DEW_ALPHA); *v = -log(1.0 + pow(*x, alpha)); } void Ddewijsian(double *x, cov_model *cov, double *v){ double alpha = P0(DEW_ALPHA), p =pow(*x, alpha - 1.0) ; *v = - alpha * p / (1.0 + *x * p); } void DDdewijsian(double *x, cov_model *cov, double *v){ double alpha = P0(DEW_ALPHA), p = pow(*x, alpha - 2.0), ha = p * *x * *x, haP1 = ha + 1.0; *v = alpha * p * (1.0 - alpha + ha) / (haP1 * haP1); } void Inversedewijsian(double *x, cov_model *cov, double *v){ double alpha = P0(DEW_ALPHA); *v = pow(exp(*x) - 1.0, 1.0 / alpha); } int checkdewijsian(cov_model *cov){ double alpha = P0(DEW_ALPHA); cov->logspeed = alpha; return NOERROR; } void rangedewijsian(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[DEW_ALPHA] = 0.0; range->max[DEW_ALPHA] = 2.0; range->pmin[DEW_ALPHA] = UNIT_EPSILON; range->pmax[DEW_ALPHA] = 2.0; range->openmin[DEW_ALPHA] = true; range->openmax[DEW_ALPHA] = false; } /* De Wijsian B */ #define DEW_RANGE 1 void DeWijsian(double *x, cov_model *cov, double *v){ double alpha = P0(DEW_ALPHA), range = P0(DEW_RANGE); *v = (*x >= range) ? 0.0 : 1.0 - log(1.0 + pow(*x, alpha)) / log(1.0 + pow(range, alpha)); } void InverseDeWijsian(double *x, cov_model *cov, double *v){ double alpha = P0(DEW_ALPHA), range = P0(DEW_RANGE); *v = *x >= 1.0 ? 0.0 : pow(pow(1.0 + pow(range, alpha), 1.0 - *x) - 1.0, 1.0 / alpha); } void rangeDeWijsian(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[DEW_ALPHA] = 0.0; range->max[DEW_ALPHA] = 1.0; range->pmin[DEW_ALPHA] = UNIT_EPSILON; range->pmax[DEW_ALPHA] = 1.0; range->openmin[DEW_ALPHA] = true; range->openmax[DEW_ALPHA] = false; range->min[DEW_RANGE] = 0.0; range->max[DEW_RANGE] = RF_INF; range->pmin[DEW_RANGE] = UNIT_EPSILON; range->pmax[DEW_RANGE] = 1000; range->openmin[DEW_RANGE] = true; range->openmax[DEW_RANGE] = true; } /* exponential model */ void exponential(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v){ *v = exp(- *x); } void logexponential(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v, double *sign){ *v = - *x; *sign = 1.0; } void TBM2exponential(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v) { double y = *x; *v = (y==0.0) ? 1.0 : 1.0 - PIHALF * y * I0mL0(y); } void Dexponential(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v){ *v = - exp(- *x); } void DDexponential(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v){ *v = exp(-*x); } void Inverseexponential(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v){ *v = (*x == 0.0) ? RF_INF : -log(*x); } void nonstatLogInvExp(double *x, cov_model *cov, double *left, double *right){ double z = *x <= 0.0 ? - *x : 0.0; int d, dim = cov->tsdim; for (d=0; dtsdim; double x2 = 0.0, dim12 = 0.5 * ((double) (dim + 1)); for (d=0; dtsdim; double D = (double) dim; if (cov->role == ROLE_GAUSS && cov->method==SpectralTBM) { spec_properties *cs = &(s->spec); if (cov->tsdim <= 2) return NOERROR; cs->density = densityexponential; return search_metropolis(cov, s); } else if (hasAnyShapeRole(cov)) { //Inverseexponential(&GLOBAL.mpp. about_ zero, NULL, &(cov->mpp.refradius)); // R *= GLOBAL.mpp.radius_natscale_factor; /* if (cov->mpp.moments >= 1) { int xi, d; double i[3], dimfak, Rfactor, sum, dimHalf = 0.5 * D; dimfak = gammafn(D); for (xi=1; xi<=2; xi++) { R = xi * cov->mpp.refradius; // // http://de.wikipedia.org/wiki/Kugel i[xi] = dimfak * 2 * pow(M_PI / (double) (xi*xi), dimHalf) / gammafn(dimHalf); if (R < RF_INF) { // Gradstein 3.351 fuer n=d-1 //printf("here\n"); for (sum = 1.0, factor=1.0, d=1; dmpp.mM[1] = cov->mpp.mMplus[1] = i[1]; if (cov->mpp.moments >= 2) { cov->mpp.mM[2] = cov->mpp.mMplus[2] = i[2]; } } */ assert(cov->mpp.maxheights[0] == 1.0); if (cov->mpp.moments >= 1) { cov->mpp.mM[1]= cov->mpp.mMplus[1] = SurfaceSphere(dim - 1, 1.0) * gammafn(D); } } else ILLEGAL_ROLE; return NOERROR; } void do_exp(cov_model VARIABLE_IS_NOT_USED *cov, storage VARIABLE_IS_NOT_USED *s) { //mppinfotype *info = &(s->mppinfo); //info->radius = cov->mpp.refradius; } void spectralexponential(cov_model *cov, storage *S, double *e) { spectral_storage *s = &(S->Sspectral); if (cov->tsdim <= 2) { double A = 1.0 - UNIFORM_RANDOM; E12(s, cov->tsdim, sqrt(1.0 / (A * A) - 1.0), e); } else { metropolis(cov, S, e); } } int checkexponential(cov_model *cov) { if (cov->tsdim > 2) cov->pref[CircEmbedCutoff] = cov->pref[CircEmbedIntrinsic] = PREF_NONE; if (cov->tsdim != 2) cov->pref[Hyperplane] = PREF_NONE; return NOERROR; } int hyperexponential(double radius, double *center, double *rx, cov_model VARIABLE_IS_NOT_USED *cov, bool simulate, double ** Hx, double ** Hy, double ** Hr) { // lenx : half the length of the rectangle // center : center of the rectangle // simulate=false: estimated number of lines returned; // simulate=true: number of simulated lines returned; // hx, hy : direction of line // hr : distance of the line from the origin // rectangular area where center gives the center // // the function expects scale = 1; double lambda, phi, lx, ly, *hx, *hy, *hr; long i, p, q=RF_NA; int k, err; assert(cov->tsdim==2); // we should be in two dimensions // first, we simulate the lines for a rectangle with center (0,0) // and half the side length equal to lenx lx = rx[0]; ly = rx[1]; lambda = TWOPI * radius * 0.5; /* total, integrated, intensity */ // 0.5 in order to get scale 1 if (!simulate) return lambda < 999999 ? (int) lambda : 999999 ; assert(*Hx==NULL); assert(*Hy==NULL); assert(*Hr==NULL); p = (long) rpois(lambda); if ((hx=*Hx=(double *) MALLOC(sizeof(double) * (p + 8 * sizeof(int))))==NULL|| (hy=*Hy=(double *) MALLOC(sizeof(double) * (p + 8 *sizeof(int))))==NULL|| (hr=*Hr=(double *) MALLOC(sizeof(double) * (p + 8 * sizeof(int))))==NULL){ err=ERRORMEMORYALLOCATION; goto ErrorHandling; } /* creating the lines; some of the lines are not relevant as they do not intersect the rectangle investigated --> k!=4 (it is checked if all the corners of the rectangle are on one side (?) ) */ q=0; for(i=0; iinstances = 1; li->value[0] = 1.0; // q[CUTOFF_A] li->msg[0] = MSGLOCAL_OK; } void ieinitExp(cov_model VARIABLE_IS_NOT_USED *cov, localinfotype *li) { li->instances = 1; li->value[0] = 1.0; li->msg[0] = MSGLOCAL_OK; } void DrawMixExp(cov_model VARIABLE_IS_NOT_USED *cov, double *random) { // GR 3.325: int_-infty^infty exp(x^2/2 - b/x^2) = exp(-\sqrt b) double x = GAUSS_RANDOM(1.0); *random = 1.0 / (x * x); } double LogMixDensExp(double VARIABLE_IS_NOT_USED *x, double VARIABLE_IS_NOT_USED logV, cov_model VARIABLE_IS_NOT_USED *cov) { // todo: check use of mixdens --- likely to programme it now completely differently return 0.0; } // Brownian motion void fractalBrownian(double *x, cov_model *cov, double *v) { double alpha = P0(BROWN_ALPHA); ///PMI(cov); *v = - pow(*x, alpha);//this is an invalid covariance function! // keep definition such that the value at the origin is 0 } //begin void logfractalBrownian(double *x, cov_model *cov, double *v, double *sign) { double alpha = P0(BROWN_ALPHA); *v = log(*x) * alpha;//this is an invalid covariance function! *sign = -1.0; // keep definition such that the value at the origin is 0 } /* fractalBrownian: first derivative at t=1 */ void DfractalBrownian(double *x, cov_model *cov, double *v) {// FALSE VALUE FOR *x==0 and alpha < 1 double alpha = P0(BROWN_ALPHA); *v = (*x != 0.0) ? -alpha * pow(*x, alpha - 1.0) : alpha > 1.0 ? 0.0 : alpha < 1.0 ? RF_NEGINF : -1.0; } /* fractalBrownian: second derivative at t=1 */ void DDfractalBrownian(double *x, cov_model *cov, double *v) {// FALSE VALUE FOR *x==0 and alpha < 2 double alpha = P0(BROWN_ALPHA); *v = (alpha == 1.0) ? 0.0 : (*x != 0.0) ? -alpha * (alpha - 1.0) * pow(*x, alpha - 2.0) : alpha < 1.0 ? RF_INF : alpha < 2.0 ? RF_NEGINF : -2.0; } void D3fractalBrownian(double *x, cov_model *cov, double *v) {// FALSE VALUE FOR *x==0 and alpha < 2 double alpha = P0(BROWN_ALPHA); *v = alpha == 1.0 || alpha == 2.0 ? 0.0 : (*x != 0.0) ? -alpha * (alpha - 1.0) * (alpha - 2.0) * pow(*x, alpha-3.0) : alpha < 1.0 ? RF_NEGINF : RF_INF; } void D4fractalBrownian(double *x, cov_model *cov, double *v) {// FALSE VALUE FOR *x==0 and alpha < 2 double alpha = P0(BROWN_ALPHA); *v = alpha == 1.0 || alpha == 2.0 ? 0.0 : (*x != 0.0) ? -alpha * (alpha - 1.0) * (alpha - 2.0) * (alpha - 3.0) * pow(*x, alpha-4.0) : alpha < 1.0 ? RF_INF : RF_NEGINF; } int checkfractalBrownian(cov_model *cov){ double alpha = P0(BROWN_ALPHA); cov->logspeed = RF_INF; cov->full_derivs = alpha <= 1.0 ? 0 : alpha < 2.0 ? 1 : cov->rese_derivs; cov->taylor[0][TaylorPow] = cov->tail[0][TaylorPow] = alpha; return NOERROR; } int initfractalBrownian(cov_model *cov, storage VARIABLE_IS_NOT_USED *s) { double alpha = P0(BROWN_ALPHA); cov->taylor[0][TaylorPow] = cov->tail[0][TaylorPow] = alpha; return NOERROR; } void InversefractalBrownian(double *x, cov_model *cov, double *v) { double alpha = P0(BROWN_ALPHA); *v = - pow(*x, 1.0 / alpha);//this is an invalid covariance function! // keep definition such that the value at the origin is 0 } void rangefractalBrownian(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[BROWN_ALPHA] = 0.0; range->max[BROWN_ALPHA] = 2.0; range->pmin[BROWN_ALPHA] = UNIT_EPSILON; range->pmax[BROWN_ALPHA] = 2.0; range->openmin[BROWN_ALPHA] = true; range->openmax[BROWN_ALPHA] = false; } void ieinitBrownian(cov_model *cov, localinfotype *li) { li->instances = 1; li->value[0] = (cov->tsdim <= 2) ? ((P0(BROWN_ALPHA) <= 1.5) ? 1.0 : 2.0) : ((P0(BROWN_ALPHA) <= 1.0) ? 1.0 : 2.0); li->msg[0] = cov->tsdim <= 3 ? MSGLOCAL_OK : MSGLOCAL_JUSTTRY; } /* FD model */ #define FD_ALPHA 0 void FD(double *x, cov_model *cov, double *v){ double alpha = P0(FD_ALPHA), y, d, k, skP1; static double dold=RF_INF; static double kold, sk; d = alpha * 0.5; y = *x; if (y == RF_INF) {*v = 0.0; return;} k = trunc(y); if (dold!=d || kold > k) { sk = 1; kold = 0.0; } // sign (-1)^k is (kold+d), 16.11.03, checked. for (; koldmin[FD_ALPHA] = -1.0; range->max[FD_ALPHA] = 1.0; range->pmin[FD_ALPHA] = range->min[FD_ALPHA] + UNIT_EPSILON; range->pmax[FD_ALPHA] = range->max[FD_ALPHA] - UNIT_EPSILON; range->openmin[FD_ALPHA] = false; range->openmax[FD_ALPHA] = true; } /* fractgauss */ #define FG_ALPHA 0 void fractGauss(double *x, cov_model *cov, double *v){ double y = *x, alpha = P0(FG_ALPHA); *v = (y == 0.0) ? 1.0 : (y==RF_INF) ? 0.0 : 0.5 *(pow(y + 1.0, alpha) - 2.0 * pow(y, alpha) + pow(fabs(y - 1.0),alpha)); } void rangefractGauss(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[FG_ALPHA] = 0.0; range->max[FG_ALPHA] = 2.0; range->pmin[FG_ALPHA] = UNIT_EPSILON; range->pmax[FG_ALPHA] = 2.0; range->openmin[FG_ALPHA] = true; range->openmax[FG_ALPHA] = false; } /* Gausian model */ void Gauss(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v) { *v = exp(- *x * *x); } void logGauss(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v, double *sign) { *v = - *x * *x; *sign = 1.0; } void DGauss(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v) { double y = *x; *v = -2.0 * y * exp(- y * y); } void DDGauss(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v) { double y = *x * *x; *v = (4.0 * y - 2.0)* exp(- y); } void D3Gauss(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v) { double y = *x * *x; *v = *x * (12 - 8 * y) * exp(- y); } void D4Gauss(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v) { double y = *x * *x; *v = ((16 * y - 48) * y + 12) * exp(- y); } void InverseGauss(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v) { *v = sqrt(-log(*x)); } void nonstatLogInvGauss(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *left, double *right) { double z = *x <= 0.0 ? sqrt(- *x) : 0.0; int d, dim = cov->tsdim; for (d=0; dtsdim; double x2=0.0; for (d=0; dtsdim; ASSERT_NEWMODEL_NOT_NULL; // APMI(cov); //printf("role %s\n", ROLENAMES[cov->role]); assert(false); // printf("xxx\n"); return NOERROR; switch (cov->role) { case ROLE_POISSON_GAUSS :// optimierte density fuer den Gauss-Fall double invscale; addModel(newmodel, GAUSS); addModel(newmodel, DOLLAR); kdefault(*newmodel, DSCALE, INVSQRTTWO); addModel(newmodel, TRUNCSUPPORT); InverseGauss(&GLOBAL.mpp.about_zero, cov, &invscale); kdefault(*newmodel, TRUNC_RADIUS, invscale); break; case ROLE_MAXSTABLE : // optimierte density fuer den Gauss-Fall // crash(); addModel(newmodel, GAUSS_DISTR); // to kdefault(*newmodel, GAUSS_DISTR_MEAN, 0.0); kdefault(*newmodel, GAUSS_DISTR_SD, INVSQRTTWO); return NOERROR; default : ILLEGAL_ROLE_STRUCT; } return NOERROR; } double IntUdeU2_intern(int d, double R, double expMR2) { // int_0^R u^{d-1} exp(-u^2) \D u return d == 0 ? (pnorm(R, 0.0, INVSQRTTWO, 1.0, 0.0) - 0.5) * SQRTPI : d == 1 ? 0.5 * (1.0 - expMR2) : 0.5 * (expMR2 + (d - 1.0) * IntUdeU2_intern(d - 2, R, expMR2)); } double IntUdeU2(int d, double R) { // int_0^R u^{d-1} exp(-u^2) \D u return IntUdeU2_intern(d, R, exp(-R*R)); } int initGauss(cov_model *cov, storage *s) { if (hasNoRole(cov)) return NOERROR; if (cov->role == ROLE_GAUSS && cov->method==SpectralTBM) { // APMI(cov); spec_properties *cs = &(s->spec); if (cov->tsdim <= 2) return NOERROR; cs->density = densityGauss; return search_metropolis(cov, s); } else if (hasAnyShapeRole(cov)) { // int_{b(0,R) e^{-a r^2} dr = d b_d int_0^R r^{d-1} e^{-a r^2} dr // where a = 2.0 * xi / sigma^2 // here : 2.0 is a factor so that the mpp function leads to the // gaussian covariance model exp(-x^2) // xi : 1 : integral () // 2 : integral ()^2 double R = RF_INF; // InverseGauss(&GLOBAL.mpp.about_zero, NULL, &R); int dim = cov->tsdim; assert(cov->nr == GAUSS); assert(cov->mpp.maxheights[0] = 1.0); if (cov->mpp.moments >= 1) { cov->mpp.mM[1] = cov->mpp.mMplus[1] = SurfaceSphere(dim - 1, 1.0) * IntUdeU2(dim - 1, R); int i; for (i=2; i<=cov->mpp.moments; i++) { cov->mpp.mM[i] = cov->mpp.mM[1] * pow((double) i, -0.5 * dim); } } cov->mpp.maxheights[0] = 1.0; //APMI(cov); } else ILLEGAL_ROLE; // printf("G %f %f %f %f\n", // cov->mpp.refradius, cov->mpp.maxheights[0], cov->mpp.mMplus, /// cov->mpp.mM2); return NOERROR; } void do_Gauss(cov_model VARIABLE_IS_NOT_USED *cov, storage VARIABLE_IS_NOT_USED *s) { //mppinfotype *info = &(s->mppinfo); //info->radius = cov->mpp.refradius; } void spectralGauss(cov_model *cov, storage *S, double *e) { spectral_storage *s = &(S->Sspectral); if (cov->tsdim <= 2) { E12(s, cov->tsdim, 2.0 * sqrt(-log(1.0 - UNIFORM_RANDOM)), e); // printf("spg: %d %f %f\n", cov->tsdim, e[0], e[1]); } else { metropolis(cov, S, e); } } void DrawMixGauss(cov_model VARIABLE_IS_NOT_USED *cov, double VARIABLE_IS_NOT_USED *random) { *random = 1.0; } double LogMixDensGauss(double VARIABLE_IS_NOT_USED *x, double VARIABLE_IS_NOT_USED logV, cov_model VARIABLE_IS_NOT_USED *cov) { return 0.0; } /* void densGauss(double *x, cov_model *cov, double *v) { int factor[MAXMPPDIM+1] = {0, 1 / M_SQRT_PI, INVPI, INVPI / M_SQRT_PI, INVPI * INVPI}, dim = cov->tsdim; *v = factor[dim] * exp(- *x * *x); } */ /* void getMassGauss(double *a, cov_model *cov, double *kappas, double *m) { int i, j, k, kold, dim = cov->tsdim; double val[MAXMPPDIM + 1], sqrt2pi = SQRT2 * SQRTPI, factor[MAXMPPDIM+1] = {1, sqrt(2) / M_SQRT_PI, 2 * INVPI, 2 * sqrt(2) * INVPI / M_SQRT_PI, 4 * INVPI * INVPI}; val[0] = 1.0; for (i=1; i<=dim; i++) val[i] = (2.0 * pnorm(SQRT2 * a[i], 0.0, 1.0, 0, 0) - 1.0) * M_SQRT_PI; for (k=kold=i=0; ilogspeed = RF_INF; return NOERROR; } void rangegenBrownian(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[BROWN_ALPHA] = 0.0; range->max[BROWN_ALPHA] = 2.0; range->pmin[BROWN_ALPHA] = UNIT_EPSILON; range->pmax[BROWN_ALPHA] = 2.0 - UNIT_EPSILON; range->openmin[BROWN_ALPHA] = true; range->openmax[BROWN_ALPHA] = false; range->min[BROWN_GEN_BETA] = 0.0; range->max[BROWN_GEN_BETA] = 2.0; range->pmin[BROWN_GEN_BETA] = UNIT_EPSILON; range->pmax[BROWN_GEN_BETA] = 2.0 - UNIT_EPSILON; range->openmin[BROWN_GEN_BETA] = true; range->openmax[BROWN_GEN_BETA] = false; } /* gencauchy */ #define GENC_ALPHA 0 #define GENC_BETA 1 void generalisedCauchy(double *x, cov_model *cov, double *v){ double alpha = P0(GENC_ALPHA), beta=P0(GENC_BETA); *v = pow(1.0 + pow(*x, alpha), -beta/alpha); } void DgeneralisedCauchy(double *x, cov_model *cov, double *v){ double alpha = P0(GENC_ALPHA), beta=P0(GENC_BETA), ha, y=*x; if (y ==0.0) { *v = ((alpha > 1.0) ? 0.0 : (alpha < 1.0) ? -INFTY : -beta); } else { ha=pow(y, alpha - 1.0); *v = -beta * ha * pow(1.0 + ha * y, -beta / alpha - 1.0); } } void DDgeneralisedCauchy(double *x, cov_model *cov, double *v){ double alpha = P0(GENC_ALPHA), beta=P0(GENC_BETA), ha, y=*x; if (y ==0.0) { *v = ((alpha==2.0) ? beta * (beta + 1.0) : INFTY); } else { ha=pow(y, alpha); *v = beta * ha / (y * y) * (1.0 - alpha + (1.0 + beta) * ha) * pow(1.0 + ha, -beta / alpha - 2.0); } } void loggeneralisedCauchy(double *x, cov_model *cov, double *v, double *sign){ double alpha = P0(GENC_ALPHA), beta=P0(GENC_BETA); *v = log(1.0 + pow(*x, alpha)) * -beta/alpha; *sign = 1.0; } void InversegeneralisedCauchy(double *x, cov_model *cov, double *v) { double alpha = P0(GENC_ALPHA), beta=P0(GENC_BETA); *v = (*x == 0.0) ? RF_INF : pow(pow(*x, -alpha / beta) - 1.0, 1.0 / alpha); //printf("genc %f %f; alpha= %f %f \n", *x, *v, alpha, beta); // MLE works much better with 0.01 then with 0.05 } int checkgeneralisedCauchy(cov_model *cov){ //double alpha = P0(GENC_ALPHA); if (cov->tsdim > 2) cov->pref[CircEmbedCutoff] = cov->pref[CircEmbedIntrinsic] = PREF_NONE; return NOERROR; } bool TypegeneralisedCauchy(Types required, cov_model *cov) { if (required==PosDefType || required==NegDefType || required==ShapeType) return true; double *alpha = P(GENC_ALPHA); if (alpha==NULL || !ISNAN(*alpha) || cov->kappasub[GENC_ALPHA]!=NULL) return false; return *alpha <= 1.0 && required==TcfType; } void rangegeneralisedCauchy(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range) { range->min[GENC_ALPHA] = 0.0; range->max[GENC_ALPHA] = 2.0; range->pmin[GENC_ALPHA] = 0.05; range->pmax[GENC_ALPHA] = 2.0; range->openmin[GENC_ALPHA] = true; range->openmax[GENC_ALPHA] = false; range->min[GENC_BETA] = 0.0; range->max[GENC_BETA] = RF_INF; range->pmin[GENC_BETA] = 0.05; range->pmax[GENC_BETA] = 10.0; range->openmin[GENC_BETA] = true; range->openmax[GENC_BETA] = true; } void coinitgenCauchy(cov_model *cov, localinfotype *li) { double thres[2] = {0.5, 1.0}, alpha=P0(GENC_ALPHA); if (alpha <= thres[0]) { li->instances = 2; li->value[0] = 0.5; li->value[1] = 1.0; li->msg[0] = li->msg[1] = MSGLOCAL_OK; } else { li->instances = 1; li->value[0] = 1.0; // q[CUTOFF_A] li->msg[0] = (alpha <= thres[1]) ? MSGLOCAL_OK : MSGLOCAL_JUSTTRY; } } void ieinitgenCauchy(cov_model *cov, localinfotype *li) { li->instances = 1; if (P0(GENC_ALPHA) <= 1.0) { li->value[0] = 1.0; li->msg[0] = MSGLOCAL_OK; } else { li->value[0] = 1.5; li->msg[0] = MSGLOCAL_JUSTTRY; } } /* epsC -> generalised Cauchy : leading 1 is now an eps */ #define EPS_ALPHA 0 #define EPS_BETA 1 #define EPS_EPS 2 void epsC(double *x, cov_model *cov, double *v){ double alpha = P0(EPS_ALPHA), beta=P0(EPS_BETA), eps=P0(EPS_EPS); *v = pow(eps + pow(*x, alpha), -beta/alpha); } void logepsC(double *x, cov_model *cov, double *v, double *sign){ double alpha = P0(EPS_ALPHA), beta=P0(EPS_BETA), eps=P0(EPS_EPS); *v = log(eps + pow(*x, alpha)) * -beta/alpha; *sign = 1.0; } void DepsC(double *x, cov_model *cov, double *v){ double ha, y=*x, alpha = P0(EPS_ALPHA), beta=P0(EPS_BETA), eps=P0(EPS_EPS); if (y ==0.0) { *v = (eps == 0.0) ? -INFTY : ((alpha > 1.0) ? 0.0 : (alpha < 1.0) ? -INFTY : -beta); } else { ha=pow(y, alpha - 1.0); *v = -beta * ha * pow(eps + ha * y, -beta / alpha - 1.0); } } void DDepsC(double *x, cov_model *cov, double *v){ double ha, y=*x, alpha = P0(EPS_ALPHA), beta=P0(EPS_BETA), eps=P0(EPS_EPS); if (y ==0.0) { *v = (eps == 0.0) ? INFTY : ((alpha==2.0) ? beta * (beta + 1.0) : INFTY); } else { ha=pow(y, alpha); *v = beta * ha / (y * y) * ( (1.0 - alpha) * eps + (1.0 + beta) * ha) * pow(eps + ha, -beta / alpha - 2.0); } } void InverseepsC(double *x, cov_model *cov, double *v){ double alpha = P0(EPS_ALPHA), beta=P0(EPS_BETA), eps=P0(EPS_EPS); *v = (*x == 0.0) ? RF_INF : pow(pow(*x, -alpha / beta) - eps, 1.0 / alpha); } int checkepsC(cov_model *cov){ double eps=P0(EPS_ALPHA); int i, err; if (cov->tsdim > 2) cov->pref[CircEmbedCutoff] = cov->pref[CircEmbedIntrinsic] = PREF_NONE; if ((err = checkkappas(cov, false)) != NOERROR) return err; kdefault(cov, EPS_ALPHA, 1.0); kdefault(cov, EPS_BETA, 1.0); kdefault(cov, EPS_EPS, 0.0); if (ISNAN(eps) || eps == 0.0) { // cov->domown=GENERALISEDCOVARIANCE; // later for (i=CircEmbed; ipref[i] = PREF_NONE; } return NOERROR; } void rangeepsC(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[EPS_ALPHA] = 0.0; range->max[EPS_ALPHA] = 2.0; range->pmin[EPS_ALPHA] = 0.05; range->pmax[EPS_ALPHA] = 2.0; range->openmin[EPS_ALPHA] = true; range->openmax[EPS_ALPHA] = false; range->min[EPS_BETA] = 0.0; range->max[EPS_BETA] = RF_INF; range->pmin[EPS_BETA] = 0.05; range->pmax[EPS_BETA] = 10.0; range->openmin[EPS_BETA] = true; range->openmax[EPS_BETA] = true; range->min[EPS_EPS] = 0.0; range->max[EPS_EPS] = RF_INF; range->pmin[EPS_EPS] = 0.0; range->pmax[EPS_EPS] = 10.0; range->openmin[EPS_EPS] = true; // false for generlised covariance range->openmax[EPS_EPS] = true; } /* gengneiting */ #define GENGNEITING_K 0 #define GENGNEITING_MU 1 void genGneiting(double *x, cov_model *cov, double *v) { int kk = P0INT(GENGNEITING_K); double s, mu=P0(GENGNEITING_MU), y=*x; if (y >= 1.0) { *v = 0.0; return; } s = mu + 2.0 * (double) kk + 0.5; switch (kk) { case 0: *v = 1.0; break; case 1: *v = 1.0 + s*y ; break; case 2: *v = 1.0 + y * (s + y * (s*s-1.0) * ONETHIRD); break; case 3: *v = 1 + y * (s + y * (0.2 * (2.0*s*s - 3 + y * (s*s-4) * s * ONETHIRD))); break; default : BUG; } *v *= pow(1.0 - y, s); // APMI(cov->calling->calling); } // control thanks to http://calc101.com/webMathematica/derivatives.jsp#topdoit void DgenGneiting(double *x, cov_model *cov, double *v) { int kk = P0INT(GENGNEITING_K); double s, mu=P0(GENGNEITING_MU), y=*x; if (y >= 1.0) { *v = 0.0; return; } s = mu + 2.0 * (double) kk + 0.5; switch (kk) { case 0: *v = s; break; case 1: *v = y * s * (s + 1.0); break; case 2: *v = ONETHIRD * (s * s + 3.0 * s + 2.0) * y * ((s - 1.0) * y + 1.0); break; case 3: *v = y * (s * (s + 5) + 6) * (y * (s * (s-2) * y + 3 * s - 3) + 3) / 15.0; break; default : BUG; } *v *= -pow(1.0 - y, s-1.0); } void DDgenGneiting(double *x, cov_model *cov, double *v){ int kk = P0INT(GENGNEITING_K); double s, mu=P0(GENGNEITING_MU), y=*x; if (y >= 1.0) { *v = 0.0; return; } s = mu + 2.0 * (double) kk + 0.5; switch (kk) { case 0: *v = s * (s-1); break; case 1: *v = s * (s + 1.0) * (s * y - 1) ; break; case 2: { double s2; s2 = s * s; *v = ONETHIRD * (s2 + 3.0 * s + 2.0) * ( y * ((s2 - 1) * y - s + 2) - 1); } break; case 3: double s2; s2 = s * s; *v = (s2 + 5 * s + 6) / 15.0 * (y * (y * ((s2 - 4) * s * y + 6 * s - 3) -3 * s + 6) - 3); break; default : BUG; } *v *= pow(1.0 - y, s - 2.0); } int checkgenGneiting(cov_model *cov){ double mu=P0(GENGNEITING_MU), dim = 2.0 * mu; cov->maxdim = (ISNAN(dim) || dim >= INFDIM) ? INFDIM : (int) dim; return NOERROR; } void rangegenGneiting(cov_model *cov, range_type *range){ range->min[GENGNEITING_K] = range->pmin[GENGNEITING_K] = 0; range->max[GENGNEITING_K] = range->pmax[GENGNEITING_K] = 3; range->openmin[GENGNEITING_K] = false; range->openmax[GENGNEITING_K] = false; range->min[GENGNEITING_MU] = 0.5 * (double) cov->tsdim; range->max[GENGNEITING_MU] = RF_INF; range->pmin[GENGNEITING_MU] = range->min[GENGNEITING_MU]; range->pmax[GENGNEITING_MU] = range->pmin[GENGNEITING_MU] + 10.0; range->openmin[GENGNEITING_MU] = false; range->openmax[GENGNEITING_MU] = true; } /* double porcusG(double t, double nu, double mu, double gamma) { double t0 = fabs(t); if (t0 > mu) return 0.0; return pow(t0, nu) * pow(1.0 - t0 / mu, gamma); } */ #define GNEITING_K GENGNEITING_K // important to keep ! #define GNEITING_MU 1 #define GNEITING_S 2 #define GNEITING_SRED 3 #define GNEITING_GAMMA 4 #define GNEITING_CDIAG 5 #define GNEITING_RHORED 6 #define GNEITING_C 7 double biGneitQuot(double t, double* scale, double *gamma) { double t0 = fabs(t); return pow(1.0 - t0 / scale[0], gamma[0]) * pow(1.0 - t0 / scale[3], gamma[3]) * pow(1.0 - t0 / scale[1], -2 * gamma[1]); } void biGneitingbasic(cov_model *cov, // double *alpha, double *scale, double *gamma, double *cc ){ double sign, x12, min, det, a, b, c, sum, k = (double) (P0INT(GNEITING_K)), kP1 = k + (k >= 1), Mu = P0(GNEITING_MU), nu = Mu + 0.5, *sdiag = P(GNEITING_S), // >= 0 s12red = P0(GNEITING_SRED), // in [0,1] s12 = s12red * (sdiag[0] <= sdiag[1] ? sdiag[0] : sdiag[1]), *tildegamma = P(GNEITING_GAMMA), // 11,22,12 *Cdiag = P(GNEITING_CDIAG), *C = P(GNEITING_C), rho = P0(GNEITING_RHORED); scale[0] = sdiag[0]; scale[1] = scale[2] = s12; // = scale[2] scale[3] = sdiag[1]; gamma[0] = tildegamma[0]; gamma[1] = gamma[2] = tildegamma[1]; //gamma[2] gamma[3] = tildegamma[2]; sum = 0.0; if (scale[0] == scale[1]) sum += gamma[0]; if (scale[0] == scale[3]) sum += gamma[3]; if (sum > 2.0 * gamma[1]) error("values of gamma not valid."); min = 1.0; a = 2 * gamma[1] - gamma[0] - gamma[3]; b = - 2 * gamma[1] * (scale[0] + scale[3]) + gamma[0] * (scale[1] + scale[3]) + gamma[3] * (scale[1] + scale[0]); c = 2 * gamma[1] * scale[0] * scale[3] - gamma[0] * scale[1] * scale[3] - gamma[3] * scale[1] * scale[0]; det = b * b - 4 * a * c; if (det >= 0) { det = sqrt(det); for (sign=-1.0; sign<=1.0; sign+=2.0) { x12 = 0.5 / a * (-b + sign * det); if (x12>0 && x12check; biwm_storage *S = cov->Sbiwm; assert(S != NULL); if (s == NULL) { PALLOC(GNEITING_S, 2, 1); s = P(GNEITING_S); s[0] = s[1] = 1.0; } if (sred == NULL) { PALLOC(GNEITING_SRED, 1, 1); sred = P(GNEITING_SRED); sred[0] = 1.0; } if (sred[0] == 1.0) { double sum =0.0; if (s[0] <= s[1]) sum += p_gamma[0]; if (s[1] <= s[0]) sum += p_gamma[2]; if (sum > 2.0 * p_gamma[1]) { SERR("if sred=1, then 2 * gamma_{12} must be greater than the (sum of) the values where 's' takes the minimal value."); } } if (S->cdiag_given) { if (cdiag == NULL) { PALLOC(GNEITING_CDIAG, 2, 1); cdiag = P(GNEITING_CDIAG); cdiag[0] = cdiag[1] = 1.0; } if (rho == NULL) QERRC(GNEITING_RHORED, "'cdiag' and 'rhored' must be set at the same time "); if (check && c != NULL) { if (cov->nrow[GNEITING_C] != 3 || cov->ncol[GNEITING_C] != 1) QERRC(GNEITING_C, "'c' must be a 3 x 1 vector"); if (fabs(c[i11] - cdiag[0]) > c[i11] * epsilon || fabs(c[i22] - cdiag[1]) > c[i22] * epsilon ) { // printf("c %f %f %f %f\n", c[i11], c[i22], cdiag[0], cdiag[1]); QERRC(GNEITING_C, "'c' does not match 'cdiag'."); } double savec12 = c[i21]; biGneitingbasic(cov, S->scale, S->gamma, S->c); // print("cc c=%f save=%f wpa=%e abs=%e c.eps=%e %d\n", // c[i21], savec12, eps, fabs(c[i21] - savec12), c[i21] * epsilon, // fabs(c[i21] - savec12) > fabs(c[i21]) * epsilon); if (fabs(c[i21] - savec12) > fabs(c[i21]) * epsilon) QERRC(GNEITING_C, "'c' does not match 'rhored'."); } else { if (PisNULL(GNEITING_C)) PALLOC(GNEITING_C, 3, 1); c = P(GNEITING_C); biGneitingbasic(cov, S->scale, S->gamma, S->c); } } else { if (c == NULL) QERRC(GNEITING_C, "either 'c' or 'rhored' must be set"); if (!ISNAN(c[i11]) && !ISNAN(c[i22]) && (c[i11] < 0.0 || c[i22] < 0.0)) QERRC(GNEITING_C, "variance parameter c[0], c[2] must be non-negative."); if (PisNULL(GNEITING_CDIAG)) PALLOC(GNEITING_CDIAG, 2, 1); if (PisNULL(GNEITING_RHORED)) PALLOC(GNEITING_RHORED, 1, 1); cdiag = P(GNEITING_CDIAG); rho = P(GNEITING_RHORED); cdiag[0] = c[i11]; cdiag[1] = c[i22]; double savec1 = c[i21]; if (savec1 == 0.0) rho[0] = 0.0; // wichtig falls c[0] oder c[2]=NA else { rho[0] = 1.0; biGneitingbasic(cov, S->scale, S->gamma, S->c); rho[0] = savec1 / c[i21]; } } biGneitingbasic(cov, S->scale, S->gamma, S->c); cov->initialised = true; return NOERROR; } void kappa_biGneiting(int i, cov_model *cov, int *nr, int *nc){ *nc = *nr = i < CovList[cov->nr].kappas? 1 : -1; if (i==GNEITING_S || i==GNEITING_CDIAG) *nr=2; else if (i==GNEITING_GAMMA || i==GNEITING_C) *nr=3 ; } void biGneiting(double *x, cov_model *cov, double *v) { double z, mu = P0(GNEITING_MU); int i; biwm_storage *S = cov->Sbiwm; assert(S != NULL); // wegen ML aufruf immer neu berechnet assert(cov->initialised); for (i=0; i<4; i++) { // print("x=%f i=%d\n", *x, i); PMI(cov->calling->calling->calling->calling); if (i==2) { v[2] = v[1]; continue; } z = fabs(*x / S->scale[i]); P(GENGNEITING_MU)[0] = mu + S->gamma[i] + 1.0; genGneiting(&z, cov, v + i); v[i] *= S->c[i]; } P(GENGNEITING_MU)[0] = mu; } void DbiGneiting(double *x, cov_model *cov, double *v){ double z, mu = P0(GENGNEITING_MU); int i; biwm_storage *S = cov->Sbiwm; assert(S != NULL); assert(cov->initialised); for (i=0; i<4; i++) { if (i==2) { v[2] = v[1]; continue; } z = fabs(*x / S->scale[i]); P(GENGNEITING_MU)[0] = mu + S->gamma[i] + 1.0; DgenGneiting(&z, cov, v + i); v[i] *= S->c[i] / S->scale[i]; } P(GENGNEITING_MU)[0] = mu; } void DDbiGneiting(double *x, cov_model *cov, double *v){ double z, mu = P0(GENGNEITING_MU); int i; biwm_storage *S = cov->Sbiwm; assert(S != NULL); assert(cov->initialised); for (i=0; i<4; i++) { if (i==2) { v[2] = v[1]; continue; } z = fabs(*x / S->scale[i]); P(GENGNEITING_MU)[0] = mu + S->gamma[i] + 1.0; DDgenGneiting(&z, cov, v + i); v[i] *= S->c[i] / (S->scale[i] * S->scale[i]); } P(GENGNEITING_MU)[0] = mu; } int checkbiGneiting(cov_model *cov) { int err; storage s; STORAGE_NULL(&s); s.check = true; if ((err = checkkappas(cov, false)) != NOERROR) return err; if (PisNULL(GNEITING_K)) QERRC(GNEITING_K, "'kappa' must be given."); if (PisNULL(GNEITING_MU)) QERRC(GNEITING_MU, "'mu' must be given."); if (PisNULL(GNEITING_GAMMA)) QERRC(GNEITING_GAMMA,"'gamma' must be given."); if (cov->Sbiwm == NULL) { cov->Sbiwm = (biwm_storage*) MALLOC(sizeof(biwm_storage)); BIWM_NULL(cov->Sbiwm); } biwm_storage *S = cov->Sbiwm; assert(S != NULL); S->cdiag_given = !PisNULL(GNEITING_CDIAG) || !PisNULL(GNEITING_RHORED); if ((err=initbiGneiting(cov, &s)) != NOERROR) return err; int dim = 2.0 * P0(GENGNEITING_MU); cov->maxdim = (ISNAN(dim) || dim >= INFDIM) ? INFDIM : (int) dim; return NOERROR; } sortsofparam paramtype_biGneiting(int k, int VARIABLE_IS_NOT_USED row, int VARIABLE_IS_NOT_USED col) { return k == GNEITING_S ? SCALEPARAM : k == GNEITING_CDIAG ? VARPARAM : k == GNEITING_C ? DONOTRETURNPARAM : (k==GNEITING_MU || k==GNEITING_GAMMA) ? CRITICALPARAM : ANYPARAM; } void rangebiGneiting(cov_model *cov, range_type *range){ // *n = P0(GNEITING_K], range->min[GNEITING_K] = range->pmin[GNEITING_K] = 0; range->max[GNEITING_K] = range->pmax[GNEITING_K] = 3; range->openmin[GNEITING_K] = false; range->openmax[GNEITING_K] = false; // *mu = P0(GNEITING_MU], range->min[GNEITING_MU] = 0.5 * (double) cov->tsdim; range->max[GNEITING_MU] = RF_INF; range->pmin[GNEITING_MU] = range->min[GNEITING_MU]; range->pmax[GNEITING_MU] = range->pmin[GNEITING_MU] + 10.0; range->openmin[GNEITING_MU] = false; range->openmax[GNEITING_MU] = true; // *scalediag = P0(GNEITING_S], range->min[GNEITING_S] = 0.0; range->max[GNEITING_S] = RF_INF; range->pmin[GNEITING_S] = 1e-2; range->pmax[GNEITING_S] = 6.0; range->openmin[GNEITING_S] = true; range->openmax[GNEITING_S] = true; // *scalered12 = P0(GNEITING_SRED], range->min[GNEITING_SRED] = 0; range->max[GNEITING_SRED] = 1; range->pmin[GNEITING_SRED] = 0.01; range->pmax[GNEITING_SRED] = 1; range->openmin[GNEITING_SRED] = true; range->openmax[GNEITING_SRED] = false; // *gamma = P0(GNEITING_GAMMA], range->min[GNEITING_GAMMA] = 0.0; range->max[GNEITING_GAMMA] = RF_INF; range->pmin[GNEITING_GAMMA] = 1e-5; range->pmax[GNEITING_GAMMA] = 100.0; range->openmin[GNEITING_GAMMA] = false; range->openmax[GNEITING_GAMMA] = true; // *c diag = P0(GNEITING_CDIAG]; range->min[GNEITING_CDIAG] = 0; range->max[GNEITING_CDIAG] = RF_INF; range->pmin[GNEITING_CDIAG] = 1e-05; range->pmax[GNEITING_CDIAG] = 1000; range->openmin[GNEITING_CDIAG] = true; range->openmax[GNEITING_CDIAG] = true; // *rho = P0(GNEITING_RHORED]; range->min[GNEITING_RHORED] = -1; range->max[GNEITING_RHORED] = 1; range->pmin[GNEITING_RHORED] = -0.95; range->pmax[GNEITING_RHORED] = 0.95; range->openmin[GNEITING_RHORED] = false; range->openmax[GNEITING_RHORED] = false; // *rho = P0(GNEITING_C]; range->min[GNEITING_C] = RF_NEGINF; range->max[GNEITING_C] = RF_INF; range->pmin[GNEITING_C] = -1000; range->pmax[GNEITING_C] = 1000; range->openmin[GNEITING_C] = true; range->openmax[GNEITING_C] = true; } /* Gneiting's functions -- alternative to Gaussian */ // #define Sqrt2TenD47 0.30089650263257344820 /* approcx 0.3 ?? */ #define NumericalScale 0.301187465825 void Gneiting(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v){ double y=*x * NumericalScale, oneMy8; if (y >= 1.0) { *v = 0.0; } else { oneMy8 = 1.0-y; oneMy8*=oneMy8; oneMy8*=oneMy8; oneMy8*=oneMy8; *v =((1.0+y * ( 8.0 + y * (25.0 + 32.0 *y)))*oneMy8); } } //void InverseGneiting(cov_model *cov, int scaling) {return 0.5854160193;} void DGneiting(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v){ double y=*x * NumericalScale, oneMy7; if (y >= 1.0) { *v = 0.0; } else { oneMy7 = 1.0-y; oneMy7 *= oneMy7; oneMy7 *= oneMy7 * oneMy7 * (1.0-y); *v = (-y) * ( 22.0 + y * (154.0 + y * 352.0)) * oneMy7 * NumericalScale; } } /* hyperbolic */ #define BOLIC_NU 0 #define BOLIC_XI 1 #define BOLIC_DELTA 2 void hyperbolic(double *x, cov_model *cov, double *v){ double sign; loghyperbolic(x, cov, v, &sign); *v = exp(*v); } void loghyperbolic(double *x, cov_model *cov, double *v, double *sign){ double nu = P0(BOLIC_NU), xi=P0(BOLIC_XI), delta=P0(BOLIC_DELTA); static double nuOld = RF_INF; static double xiOld= RF_INF; static double deltaOld = RF_INF; static double deltasq; static double xidelta; static double logconst; double y=*x; *sign = 1.0; if (y==0.0) { *v = 0.0; return; } else if (y==RF_INF) { *v = -RF_INF; *sign = 0.0; return; } if (delta==0) { // whittle matern if (nu > 80) warning("extremely imprecise results due to nu>80"); *v = logWM(y * xi, nu, 0.0); } else if (xi==0) { //cauchy => NU2 < 0 ! y /= delta; /* note change in sign as NU2<0 */ *v = log(1 + y * y) * 0.5 * nu; } else { if ((nu!=nuOld) || (xi!=xiOld) || (delta!=deltaOld)) { nuOld = nu; xiOld = xi; deltaOld = delta; deltasq = deltaOld * deltaOld; xidelta = xiOld * deltaOld; logconst = xidelta - log(bessel_k(xidelta, nuOld, 2.0)) - nu * log(deltaOld); } y=sqrt(deltasq + y * y); double xiy = xi * y; *v = logconst + nu * log(y) + log(bessel_k(xiy, nu, 2.0)) - xiy; } } void Dhyperbolic(double *x, cov_model *cov, double *v) { double nu = P0(BOLIC_NU), xi=P0(BOLIC_XI), delta=P0(BOLIC_DELTA); static double nuOld = RF_INF; static double xiOld= RF_INF; static double deltaOld = RF_INF; static double deltasq; static double xidelta; static double logconst; double s,xi_s, logs, y = *x; if (y==0.0) { *v = 1.0; return; } if (delta==0) { // whittle matern *v = xi * DWM(y * xi, nu, 0.0); *v *= xi; } else if (xi==0) { //cauchy double ha; y /= delta; ha = y * y; /* note change in sign as NU2<0 */ *v = nu * fabs(y) * pow(1.0 + ha, 0.5 * nu - 1.0) / delta; } else { if ((nu!=nu) || (xi!=xi) || (delta!=delta)) { nuOld = nu; xiOld= xi; deltaOld = delta; deltasq = deltaOld * deltaOld; xidelta = xiOld * deltaOld; logconst = xidelta - log(bessel_k(xidelta, nuOld, 2.0)) - nu * log(deltaOld); } s=sqrt(deltasq + y * y); xi_s = xi * s; logs = log(s); *v = - y * xi * exp(logconst + (nu-1.0) * logs +log(bessel_k(xi_s, nu-1.0, 2.0)) - xi_s); } } int checkhyperbolic(cov_model *cov){ double nu = P0(BOLIC_NU), xi=P0(BOLIC_XI), delta=P0(BOLIC_DELTA); char msg[255]; int i; for (i=0; i<= Nothing; i++) cov->pref[i] *= (ISNAN(nu) || nu < BesselUpperB[i]); if (nu>0) { if ((delta<0) || (xi<=0)) { sprintf(msg, "xi>0 and delta>=0 if nu>0. Got nu=%f and delta=%f for xi=%f", nu, delta, xi); SERR(msg); } } else if (nu<0) { if ((delta<=0) || (xi<0)) { sprintf(msg, "xi>=0 and delta>0 if nu<0. Got nu=%f and delta=%f for xi=%f", nu, delta, xi); SERR(msg); } } else { // nu==0.0 if ((delta<=0) || (xi<=0)) { sprintf(msg, "xi>0 and delta>0 if nu=0. Got nu=%f and delta=%f for xi=%f", nu, delta, xi); SERR(msg); } } return NOERROR; } void rangehyperbolic(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[BOLIC_NU] = RF_NEGINF; range->max[BOLIC_NU] = RF_INF; range->pmin[BOLIC_NU] = -20.0; range->pmax[BOLIC_NU] = 20.0; range->openmin[BOLIC_NU] = true; range->openmax[BOLIC_NU] = true; int i; for (i=1; i<=2; i++) { range->min[i] = 0.0; range->max[i] = RF_INF; range->pmin[i] = 0.000001; range->pmax[i] = 10.0; range->openmin[i] = false; range->openmax[i] = true; } } /* iaco cesare model */ #define CES_NU 0 #define CES_LAMBDA 1 #define CES_DELTA 2 void IacoCesare(double *x, cov_model *cov, double *v){ double nu = P0(CES_NU), lambda=P0(CES_LAMBDA), delta=P0(CES_DELTA); *v = pow(1.0 + pow(x[0], nu) + pow(x[1], lambda), - delta); } void rangeIacoCesare(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[CES_NU] = 0.0; range->max[CES_NU] = 2.0; range->pmin[CES_NU] = 0.0; range->pmax[CES_NU] = 2.0; range->openmin[CES_NU] = true; range->openmax[CES_NU] = false; range->min[CES_LAMBDA] = 0.0; range->max[CES_LAMBDA] = 2.0; range->pmin[CES_LAMBDA] = 0.0; range->pmax[CES_LAMBDA] = 2.0; range->openmin[CES_LAMBDA] = true; range->openmax[CES_LAMBDA] = false; range->min[CES_DELTA] = 0.0; range->max[CES_DELTA] = RF_INF; range->pmin[CES_DELTA] = 0.0; range->pmax[CES_DELTA] = 10.0; range->openmin[CES_DELTA] = true; range->openmax[CES_DELTA] = true; } //int checkIacoCesare(cov_model *cov) { } /* Kolmogorov model */ void Kolmogorov(double *x, cov_model *cov, double *v){ #define fourthird 1.33333333333333333333333333333333333 #define onethird 0.333333333333333333333333333333333 int d, i, j, dim = cov->tsdim, dimP1 = dim + 1, dimsq = dim * dim; double rM23, r23, r2 =0.0; assert(dim == cov->vdim2[0] && dim == cov->vdim2[1]); for (d=0; dxdimown != 3) SERR1("dim (%d) != 3", cov->xdimown); if (cov->tsdim != cov->xdimprev || cov->tsdim != cov->xdimown) return ERRORDIM; return NOERROR; } /* local-global distinguisher */ #define LGD_ALPHA 0 #define LGD_BETA 1 void lgd1(double *x, cov_model *cov, double *v) { double y = *x, alpha = P0(LGD_ALPHA), beta=P0(LGD_BETA); *v = (y == 0.0) ? 1.0 : (y < 1.0) ? 1.0 - beta / (alpha + beta) * pow(y, alpha) : alpha / (alpha + beta) * pow(y, -beta); } void Inverselgd1(double *x, cov_model *cov, double *v) { double alpha = P0(LGD_ALPHA), beta=P0(LGD_BETA); ERR("scle of lgd1 not programmed yet"); // 19 next line?! // 1.0 / .... fehlt auch *v = (19 * alpha < beta) ? exp(log(1 - *x * (alpha + beta) / beta) / alpha) : exp(log(*x * (alpha + beta) / alpha) / beta); } void Dlgd1(double *x, cov_model *cov, double *v){ double y=*x, pp, alpha = P0(LGD_ALPHA), beta=P0(LGD_BETA); if (y == 0.0) { *v = 0.0;// falscher Wert, aber sonst NAN-Fehler# return; } pp = ( (y < 1.0) ? alpha : -beta ) - 1.0; *v = - alpha * beta / (alpha + beta) * exp(pp * y); } int checklgd1(cov_model *cov){ double dim = 2.0 * (1.5 - P0(LGD_ALPHA)); cov->maxdim = (ISNAN(dim) || dim >= 2.0) ? 2 : (int) dim; return NOERROR; } void rangelgd1(cov_model *cov, range_type *range) { range->min[LGD_ALPHA] = 0.0; range->max[LGD_ALPHA] = (cov->tsdim==2) ? 0.5 : 1.0; range->pmin[LGD_ALPHA] = 0.01; range->pmax[LGD_ALPHA] = range->max[LGD_ALPHA]; range->openmin[LGD_ALPHA] = true; range->openmax[LGD_ALPHA] = false; range->min[LGD_BETA] = 0.0; range->max[LGD_BETA] = RF_INF; range->pmin[LGD_BETA] = 0.01; range->pmax[LGD_BETA] = 20.0; range->openmin[LGD_BETA] = true; range->openmax[LGD_BETA] = true; } /* mastein */ // see Hypermodel.cc /* Whittle-Matern or Whittle or Besset ---- rescaled form of Whittle-Matern, see also there */ #define MATERN_NU_THRES 100 double WM(double x, double nu, double factor) { // check calling functions, like hyperbolic and gneiting if any changings !! return exp(logWM(x, nu, factor)); } double logWM(double x, double nu, double factor) { // check calling functions, like hyperbolic and gneiting if any changings !! static double nuOld=RF_INF; static double loggamma; double v, y, sign, nuThres = nu < MATERN_NU_THRES ? nu : MATERN_NU_THRES, scale = (factor != 0.0) ? factor * sqrt(nuThres) : 1.0; // if (!R_FINITE(nuThres) || nuThres < 0.1 || nuThres > 10) printf("X %f\n", nuThres); if (x > LOW_BESSELK) { if (nuThres != nuOld) { nuOld = nuThres; loggamma = lgammafn(nuThres); } y = x * scale; v = LOG2 + nuThres * log(0.5 * y) - loggamma + log(bessel_k(y, nuThres, 2.0)) - y; } else v = 0.0; if (nu > MATERN_NU_THRES) { // factor!=0.0 && double w, g = MATERN_NU_THRES / nu; y = x * factor / 2; logGauss(&y, NULL, &w, &sign); v = v * g + (1.0 - g) * w; } // if (!R_FINITE(nuThres) ||nuThres < 0.1 || nuThres > 10) printf("Xend\n"); return v; } double DWM(double x, double nu, double factor) { static double nuOld=RF_INF; static double loggamma; double y, v, nuThres = nu < MATERN_NU_THRES ? nu : MATERN_NU_THRES, scale = (factor != 0.0) ? factor * sqrt(nuThres) : 1.0; if (x > LOW_BESSELK) { if (nuThres!=nuOld) { nuOld = nuThres; loggamma = lgammafn(nuThres); } y = x * scale; v = - 2.0 * exp(nuThres * log(0.5 * y) - loggamma + log(bessel_k(y, nuThres - 1.0, 2.0)) - y); } else { v = (nuThres > 0.5) ? 0.0 : (nuThres < 0.5) ? INFTY : 1.253314137; } v *= scale; if (nu > MATERN_NU_THRES) { double w, g = MATERN_NU_THRES / nu; scale = factor / 2.0; y = x * scale; DGauss(&y, NULL, &w); w *= scale; v = v * g + (1.0 - g) * w; } return v; } double DDWM(double x, double nu, double factor) { static double nuOld=RF_INF; static double gamma; double y, v, nuThres = nu < MATERN_NU_THRES ? nu : MATERN_NU_THRES, scale = (factor != 0.0) ? factor * sqrt(nuThres) : 1.0, scaleSq = scale * scale; if (x > LOW_BESSELK) { if (nuThres!=nuOld) { nuOld = nuThres; gamma = gammafn(nuThres); } y = x * scale; v = pow(0.5 * y , nuThres - 1.0) / gamma * (- bessel_k(y, nuThres - 1.0, 1.0) + y * bessel_k(y, nuThres - 2.0, 1.0)); } else { v = (nu > 1.0) ? -0.5 / (nu - 1.0) : INFTY; } v *= scaleSq; if (nu > MATERN_NU_THRES) { double w, g = MATERN_NU_THRES / nu; scale = factor / 2.0; scaleSq = scale * scale; y = x * scale; DDGauss(&y, NULL, &w); w *= scaleSq; v = v * g + (1.0 - g) * w; } return v; } double D3WM(double x, double nu, double factor) { static double nuOld=RF_INF; static double gamma; double y, v, nuThres = nu < MATERN_NU_THRES ? nu : MATERN_NU_THRES, scale = (factor != 0.0) ? factor * sqrt(nuThres) : 1.0, scaleSq = scale * scale; if (x > LOW_BESSELK) { if (nuThres!=nuOld) { nuOld = nuThres; gamma = gammafn(nuThres); } y = x * scale; v = pow(0.5 * y , nuThres - 1.0) / gamma * ( 3.0 * bessel_k(y, nuThres - 2.0, 1.0) -y * bessel_k(y, nuThres - 3.0, 1.0)); } else { v = 0.0; } v *= scaleSq * scale; if (nu > MATERN_NU_THRES) { double w, g = MATERN_NU_THRES / nu; scale = factor / 2.0; scaleSq = scale * scale; y = x * scale; D3Gauss(&y, NULL, &w); w *= scaleSq * scale; v = v * g + (1.0 - g) * w; } return v; } double D4WM(double x, double nu, double factor) { static double nuOld=RF_INF; static double gamma; double y, v, nuThres = nu < MATERN_NU_THRES ? nu : MATERN_NU_THRES, scale = (factor != 0.0) ? factor * sqrt(nuThres) : 1.0, scaleSq = scale * scale; if (x > LOW_BESSELK) { if (nuThres!=nuOld) { nuOld = nuThres; gamma = gammafn(nuThres); } y = x * scale; v = 0.25 * pow(0.5 * y , nuThres - 3.0) / gamma * (+ 6.0 * (nuThres - 3.0 - y * y) * bessel_k(y, nuThres - 3.0, 1.0) + y * (3.0 + y * y) * bessel_k(y, nuThres - 4.0, 1.0)); } else { v = (nuThres > 2.0) ? 0.75 / ((nuThres - 1.0) * (nuThres - 2.0)) : INFTY; } v *= scaleSq * scaleSq; if (nu > MATERN_NU_THRES) { double w, g = MATERN_NU_THRES / nu; scale = factor / 2.0; scaleSq = scale * scale; y = x * scale; D4Gauss(&y, NULL, &w); w *= scaleSq * scaleSq; v = v * g + (1.0 - g) * w; } return v; } double ScaleWM(double nu){ // it is working reasonably well if nu is in [0.001,100] // happy to get any better suggestion!! static int nstuetz = 19; static double stuetz[]= {1.41062516176753e-14, 4.41556861847671e-12, 2.22633601732610e-06, 1.58113643548649e-03, 4.22181082102606e-02, 2.25024764696152e-01, 5.70478218148777e-01, 1.03102016706644e+00, 1.57836638352906e+00, 2.21866372852304e+00, 2.99573229151620e+00, 3.99852231863082e+00, 5.36837527567695e+00, 7.30561120838150e+00, 1.00809957038601e+01, 1.40580075785156e+01, 1.97332533513488e+01, 2.78005149402352e+01, 3.92400265713477e+01}; static int stuetzorigin = 11; return interpolate(log(nu) * INVLOG2, stuetz, nstuetz, stuetzorigin, 1.5, 5); } int checkWM(cov_model *cov) { static double spectrallimit=0.17, spectralbest=0.4; double notinvnu, nu; int i, err; bool isna_nu; if ((err = checkkappas(cov, false)) != NOERROR) return err; if (PisNULL(WM_NU)) QERRC(0, "parameter unset"); nu = (PINT(WM_NOTINV) == NULL || ISNAN(notinvnu = (double) (P0INT(WM_NOTINV))) || notinvnu != 0.0) ? P0(WM_NU) : 1.0 / P0(WM_NU); isna_nu = ISNAN(nu); for (i=0; i<= Nothing; i++) cov->pref[i] *= isna_nu || nu < BesselUpperB[i]; if (nupref[SpectralTBM] = (nu < spectrallimit) ? PREF_NONE : 3; } if (cov->tsdim > 2) cov->pref[CircEmbedCutoff] = cov->pref[CircEmbedIntrinsic] = PREF_NONE; if (nu > 2.5) cov->pref[CircEmbed] = 2; cov->full_derivs = isna_nu ? -1 : (int) (nu - 1.0); return NOERROR; } bool TypeWM(Types required, cov_model *cov) { if (required==PosDefType || required==NegDefType || required==ShapeType) return true; double *nu = P(WM_NU); if (nu==NULL || ISNAN(*nu) || cov->kappasub[WM_NU]!=NULL) return false; return *nu <= 1.0 && required==TcfType; } void rangeWM(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[WM_NU] = 0.0; range->max[WM_NU] = RF_INF; range->pmin[WM_NU] = 1e-1; range->pmax[WM_NU] = 10.0; range->openmin[WM_NU] = true; range->openmax[WM_NU] = true; range->min[WM_NOTINV] = 0.0; range->max[WM_NOTINV] = 1.0; range->pmin[WM_NOTINV] = 0.0; range->pmax[WM_NOTINV] = 1.0; range->openmin[WM_NOTINV] = false; range->openmax[WM_NOTINV] = false; } void ieinitWM(cov_model *cov, localinfotype *li) { double nu = (PINT(WM_NOTINV) == NULL || P0INT(WM_NOTINV)) ? P0(WM_NU) : 1.0 / P0(WM_NU); // intrinsic_rawr li->instances = 1; if (nu <= 0.5) { li->value[0] = 1.0; li->msg[0] = MSGLOCAL_OK; } else { li->value[0] = 1.5; li->msg[0] = MSGLOCAL_JUSTTRY; } } void coinitWM(cov_model *cov, localinfotype *li) { // cutoff_A double thres[2] = {0.25, 0.5}, nu = (PINT(WM_NOTINV) == NULL || P0INT(WM_NOTINV)) ? P0(WM_NU) : 1.0 / P0(WM_NU); if (nu <= thres[0]) { li->instances = 2; li->value[0] = 0.5; li->value[1] = 1.0; li->msg[0] = li->msg[1] = MSGLOCAL_OK; } else { li->instances = 1; li->value[0] = 1.0; // q[CUTOFF_A] li->msg[0] = (nu <= thres[1]) ? MSGLOCAL_OK : MSGLOCAL_JUSTTRY; } } double densityWM(double *x, cov_model *cov, double factor) { double x2, nu = P0(WM_NU), powfactor = 1.0; int d, dim = cov->tsdim; if (nu > 50) warning("nu>50 in density of matern class numerically instable. The results cannot be trusted."); if (factor == 0.0) factor = 1.0; else factor *= sqrt(nu); x2 = x[0] * x[0]; for (d=1; drole == ROLE_GAUSS && cov->method==SpectralTBM) { spec_properties *cs = &(s->spec); if (cov->tsdim <= 2) return NOERROR; cs->density = densityMatern; return search_metropolis(cov, s); } else ILLEGAL_ROLE; } void spectralMatern(cov_model *cov, storage *S, double *e) { spectral_storage *s = &(S->Sspectral); /* see Yaglom ! */ if (cov->tsdim <= 2) { double nu = P0INT(WM_NOTINV) ? P0(WM_NU) : 1.0 / P0(WM_NU); E12(s, cov->tsdim, sqrt( 2.0 * nu * (pow(1.0 - UNIFORM_RANDOM, -1.0 / nu) - 1.0) ), e); } else { metropolis(cov, S, e); } } // Brownian motion #define OESTING_BETA 0 void oesting(double *x, cov_model *cov, double *v) { // klein beta interagiert mit 'define beta Rf_beta' in Rmath double Beta = P0(OESTING_BETA), x2 = *x * *x; ///PMI(cov); *v = - x2 * pow(1 + x2, -Beta);//this is an invalid covariance function! // keep definition such that the value at the origin is 0 } //begin /* oesting: first derivative at t=1 */ void Doesting(double *x, cov_model *cov, double *v) {// FALSE VALUE FOR *x==0 and Beta < 1 double Beta = P0(OESTING_BETA), x2 = *x * *x; *v = 2 * *x * (1 + (1-Beta) * x2) * pow(1 + x2, -Beta-1); } /* oesting: second derivative at t=1 */ void DDoesting(double *x, cov_model *cov, double *v) {// FALSE VALUE FOR *x==0 and beta < 2 double Beta = P0(OESTING_BETA), x2 = *x * *x; *v = 2 * (1 + (2 - 5 * Beta) * x2 + (1 - 3 * Beta + 2 * Beta * Beta) * x2 *x2) * pow(1 + x2, -Beta-2); } int checkoesting(cov_model *cov){ // double Beta = P0(OESTING_BETA); cov->logspeed = RF_INF; cov->full_derivs = cov->rese_derivs; return NOERROR; } int initoesting(cov_model *cov, storage VARIABLE_IS_NOT_USED *s) { double Beta = P0(OESTING_BETA); cov->taylor[1][TaylorConst] = + Beta; cov->taylor[2][TaylorConst] = - 0.5 * Beta * (Beta + 1); cov->tail[0][TaylorPow] = 2 - 2 * Beta; return NOERROR; } void rangeoesting(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[OESTING_BETA] = 0.0; range->max[OESTING_BETA] = 1.0; range->pmin[OESTING_BETA] = UNIT_EPSILON; range->pmax[OESTING_BETA] = 1.0; range->openmin[OESTING_BETA] = true; range->openmax[OESTING_BETA] = false; } // Paciore und Stein // see NonIsoCovFct.cc /* penta */ void penta(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v) { /// double y=*x, y2 = y * y; *v = (y >= 1.0) ? 0.0 : (1.0 + y2 * (-7.333333333333333 + y2 * (33.0 + y * (-38.5 + y2 * (16.5 + y2 * (-5.5 + y2 * 0.833333333333333)))))); } void Dpenta(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v) { /// double y=*x, y2 = y * y; *v = (y >= 1.0) ? 0.0 : y * (-14.66666666666666667 + y2 * (132.0 + y * (-192.5 + y2 * (115.5 + y2 * (-49.5 + y2 * 9.16666666666666667))))); } void Inversepenta(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v) { *v = (*x==0.05) ? 1.0 / 1.6552838957365 : RF_NA; } /* power model */ #define POW_ALPHA 0 void power(double *x, cov_model *cov, double *v){ double alpha = P0(POW_ALPHA), y = *x; *v = (y >= 1.0) ? 0.0 : pow(1.0 - y, alpha); } //void Inversepower(cov_model *cov){ // double alpha = P0(POW_ALPHA); // return 1.0 / (1.0 - pow(0.05, 1.0 / alpha)); //} void TBM2power(double *x, cov_model *cov, double *v){ // only alpha=2 up to now ! double y = *x; if (P0(POW_ALPHA) != 2.0) ERR("TBM2 of power only allowed for alpha=2"); *v = (y > 1.0) ? (1.0 - 2.0 * y *(asin(1.0 / y) - y + sqrt(y * y - 1.0) )) : 1.0 - y * (PI - 2.0 * y); } void Dpower(double *x, cov_model *cov, double *v){ double alpha = P0(POW_ALPHA), y = *x; *v = (y >= 1.0) ? 0.0 : - alpha * pow(1.0 - y, alpha - 1.0); } int checkpower(cov_model *cov) { double alpha = P0(POW_ALPHA); double dim = 2.0 * alpha - 1.0; cov->maxdim = (ISNAN(dim) || dim >= INFDIM) ? INFDIM-1 : (int) dim; return NOERROR; } bool Typepower(Types required, cov_model *cov) { if (required==PosDefType || required==NegDefType || required==ShapeType) return true; double *alpha = P(POW_ALPHA); if (alpha==NULL || ISNAN(*alpha) || cov->kappasub[POW_ALPHA]!=NULL) return false; return required==TcfType && *alpha <= (cov->tsdim / 2) + 1; } // range definition: // 0: min, theory, 1:max, theory // 2: min, practically 3:max, practically void rangepower(cov_model *cov, range_type *range){ range->min[POW_ALPHA] = 0.5 * (double) (cov->tsdim + 1); range->max[POW_ALPHA] = RF_INF; range->pmin[POW_ALPHA] = range->min[POW_ALPHA]; range->pmax[POW_ALPHA] = 20.0; range->openmin[POW_ALPHA] = false; range->openmax[POW_ALPHA] = true; } /* qexponential -- derivative of exponential */ #define QEXP_ALPHA 0 void qexponential(double *x, cov_model *cov, double *v){ double alpha = P0(QEXP_ALPHA), y = exp(-*x); *v = y * (2.0 - alpha * y) / (2.0 - alpha); } void Inverseqexponential(double *x, cov_model *cov, double *v){ double alpha = P0(QEXP_ALPHA); *v = -log( (1.0 - sqrt(1.0 - alpha * (2.0 - alpha) * *x)) / alpha); } void Dqexponential(double *x, cov_model *cov, double *v) { double alpha = P0(QEXP_ALPHA), y = exp(-*x); *v = y * (alpha * y - 1.0) * 2.0 / (2.0 - alpha); } void rangeqexponential(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[QEXP_ALPHA] = 0.0; range->max[QEXP_ALPHA] = 1.0; range->pmin[QEXP_ALPHA] = 0.0; range->pmax[QEXP_ALPHA] = 1.0; range->openmin[QEXP_ALPHA] = false; range->openmax[QEXP_ALPHA] = false; } /* spherical model */ void spherical(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v){ double y = *x; *v = (y >= 1.0) ? 0.0 : 1.0 + y * 0.5 * (y * y - 3.0); } // void Inversespherical(cov_model *cov){ return 1.23243208931941;} void TBM2spherical(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v){ double y = *x , y2 = y * y; *v = (y>1.0) ? (1.0- 0.75 * y * ((2.0 - y2) * asin(1.0/y) + sqrt(y2 -1.0))) : (1.0 - 0.375 * PI * y * (2.0 - y2)); } void Dspherical(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v){ double y = *x; *v = (y >= 1.0) ? 0.0 : 1.5 * (y * y - 1.0); } void DDspherical(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v){ *v = (*x >= 1.0) ? 0.0 : 3 * *x; } int structspherical(cov_model *cov, cov_model **newmodel) { return structCircSph( cov, newmodel, 3); } void dospherical(cov_model VARIABLE_IS_NOT_USED *cov, storage VARIABLE_IS_NOT_USED *s) { // todo diese void do... in Primitive necessary?? // mppinfotype *info = &(s->mppinfo); //info->radius = cov->mpp.refradius; } double alphaIntSpherical(int a) { // int r^a C(r) \D r double A = (double) a; return 1.0 / (A + 1.0) - 1.5 / (A + 2.0) + 0.5 / (A + 4.0); } int initspherical(cov_model *cov, storage VARIABLE_IS_NOT_USED *s) { int dim = cov->tsdim; if (hasNoRole(cov)) { if (cov->mpp.moments >= 1) SERR("too high moments required"); return NOERROR; } if (hasAnyShapeRole(cov)) { // PMI(cov); // print("mpp %f\n", cov->mpp.maxheights[0] ); assert(cov->mpp.maxheights[0] == 1.0); if (cov->mpp.moments >= 1) { cov->mpp.mM[1] = cov->mpp.mMplus[1] = SurfaceSphere(dim - 1, 1) * alphaIntSpherical(dim - 1); } //cov->mpp.refradius = 1.0; // APMI(cov); } else ILLEGAL_ROLE; return NOERROR; } /* stable model */ #define STABLE_ALPHA 0 void stable(double *x, cov_model *cov, double *v){ double y = *x, alpha = P0(STABLE_ALPHA); *v = (y==0.0) ? 1.0 : exp(-pow(y, alpha)); } void logstable(double *x, cov_model *cov, double *v, double *sign){ double y = *x, alpha = P0(STABLE_ALPHA); *v = (y==0.0) ? 0.0 : -pow(y, alpha); *sign = 1.0; } void Dstable(double *x, cov_model *cov, double *v){ double z, y = *x, alpha = P0(STABLE_ALPHA); if (y == 0.0) { *v = (alpha > 1.0) ? 0.0 : (alpha < 1.0) ? INFTY : 1.0; } else { z = pow(y, alpha - 1.0); *v = -alpha * z * exp(-z * y); } } /* stable: second derivative at t=1 */ void DDstable(double *x, cov_model *cov, double *v) { double z, y = *x, alpha = P0(STABLE_ALPHA), xalpha; if (y == 0.0) { *v = (alpha == 1.0) ? 1.0 : (alpha == 2.0) ? alpha * (1 - alpha) : INFTY; } else { z = pow(y, alpha - 2.0); xalpha = z * y * y; *v = alpha * (1.0 - alpha + alpha * xalpha) * z * exp(-xalpha); } } void Inversestable(double *x, cov_model *cov, double *v){ double y = *x, alpha = P0(STABLE_ALPHA); *v = y>1.0 ? 0.0 : y == 0.0 ? RF_INF : pow( - log(y), 1.0 / alpha); } void nonstatLogInversestable(double *x, cov_model *cov, double *left, double *right){ double alpha = P0(STABLE_ALPHA), z = *x <= 0.0 ? pow( - *x, 1.0 / alpha) : 0.0; int d, dim = cov->tsdim; for (d=0; dtsdim > 2) cov->pref[CircEmbedCutoff] = cov->pref[CircEmbedIntrinsic] = PREF_NONE; if (P0(STABLE_ALPHA) == 2.0) cov->pref[CircEmbed] = 2; return NOERROR; } bool Typestable(Types required, cov_model *cov) { if (required==PosDefType || required==NegDefType || required==ShapeType) return true; double *alpha = P(STABLE_ALPHA); if (alpha==NULL || ISNAN(*alpha) || cov->kappasub[STABLE_ALPHA]!=NULL) return false; return required==TcfType && *alpha <= 1; } void rangestable(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[STABLE_ALPHA] = 0.0; range->max[STABLE_ALPHA] = 2.0; range->pmin[STABLE_ALPHA] = 0.06; range->pmax[STABLE_ALPHA] = 2.0; range->openmin[STABLE_ALPHA] = true; range->openmax[STABLE_ALPHA] = false; } void coinitstable(cov_model *cov, localinfotype *li) { coinitgenCauchy(cov, li); } void ieinitstable(cov_model *cov, localinfotype *li) { ieinitgenCauchy(cov, li); } /* SPACEISOTROPIC stable model for testing purposes only */ void stableX(double *x, cov_model *cov, double *v){ double y, alpha = P0(STABLE_ALPHA); y = x[0] * x[0] + x[1] * x[1]; *v = (y==0.0) ? 1.0 : exp(-pow(y, 0.5 * alpha)); } void DstableX(double *x, cov_model *cov, double *v){ double z, y, alpha = P0(STABLE_ALPHA); y = x[0] * x[0] + x[1] * x[1]; if (y == 0.0) { *v = ((alpha > 1.0) ? 0.0 : (alpha < 1.0) ? INFTY : 1.0); } else { z = pow(y, 0.5 * alpha - 1.0); *v = -alpha * x[0] * z * exp(- z * y); } } /* END SPACEISOTROPIC stable model for testing purposes only */ /* Stein */ // see Hypermodel.cc /* stein space-time model */ #define STEIN_NU 0 #define STEIN_Z 1 void kappaSteinST1(int i, cov_model *cov, int *nr, int *nc){ *nc = 1; *nr = (i == STEIN_NU) ? 1 : (i==STEIN_Z) ? cov->tsdim - 1 : -1; } void SteinST1(double *x, cov_model *cov, double *v){ /* 2^(1-nu)/Gamma(nu) [ h^nu K_nu(h) - 2 * tau (x T z) t h^{nu-1} K_{nu-1}(h) / (2 nu + d + 1) ] \|tau z \|<=1 hence \tau z replaced by z !! */ int d, dim = cov->tsdim, time = dim - 1; double logconst, hz, y, nu = P0(STEIN_NU), *z=P(STEIN_Z); static double nuold=RF_INF; static double loggamma; static int dimold; if (nu != nuold || dimold != dim) { nuold = nu; dimold = dim; loggamma = lgammafn(nu); } hz = 0.0; y = x[time] * x[time]; for (d=0; dtsdim-1; for (d=0; d<= Nothing; d++) cov->pref[d] *= (nu < BesselUpperB[d]); if (nu >= 2.5) cov->pref[CircEmbed] = 2; if (spatialdim < 1) SERR("dimension of coordinates, including time, must be at least 2"); for (absz=0.0, d=0; d 1.0 + UNIT_EPSILON && !GLOBAL.general.skipchecks) { SERR("||z|| must be less than or equal to 1"); } return NOERROR; } double densitySteinST1(double *x, cov_model *cov) { double x2, wz, dWM, nu = P0(STEIN_NU), *z=P(STEIN_Z); int d, dim = cov->tsdim, spatialdim = dim - 1; static double nuold = RF_INF; static int dimold = -1; static double constant; static double factor; if (nu != nuold || dimold != dim) { nuold = nu; dimold = dim; constant = lgammafn(nu) - lgammafn(nu + 0.5 * dim) - dim * M_LN_SQRT_PI; factor = nu + dim; } x2 = x[spatialdim] * x[spatialdim]; // v^2 wz = 0.0; for (d=0; drole == ROLE_GAUSS && cov->method==SpectralTBM) { spec_properties *cs = &(s->spec); cs->density = densitySteinST1; return search_metropolis(cov, s); // return (cov->tsdim == 3) ? NOERROR : ERRORFAILED; } else ILLEGAL_ROLE; } void spectralSteinST1(cov_model *cov, storage *S, double *e){ // spectral_storage *s = &(S->Sspectral); metropolis(cov, S, e); } void rangeSteinST1(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[STEIN_NU] = 1.0; range->max[STEIN_NU] = RF_INF; range->pmin[STEIN_NU] = 1e-10; range->pmax[STEIN_NU] = 10.0; range->openmin[STEIN_NU] = true; range->openmax[STEIN_NU] = true; range->min[STEIN_Z] = RF_NEGINF; range->max[STEIN_Z] = RF_INF; range->pmin[STEIN_Z] = -10.0; range->pmax[STEIN_Z] = 10.0; range->openmin[STEIN_Z] = true; range->openmax[STEIN_Z] = true; } /* wave */ void wave(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v) { double y = *x; *v = (y==0.0) ? 1.0 : (y==RF_INF) ? 0 : sin(y) / y; } void Inversewave(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v) { *v = (*x==0.05) ? 1.0/0.302320850755833 : RF_NA; } int initwave(cov_model *cov, storage VARIABLE_IS_NOT_USED *s) { if (cov->role == ROLE_GAUSS && cov->method==SpectralTBM) { return (cov->tsdim <= 2) ? NOERROR : ERRORFAILED; } else ILLEGAL_ROLE; } void spectralwave(cov_model *cov, storage *S, double *e) { spectral_storage *s = &(S->Sspectral); /* see Yaglom ! */ double x; x = UNIFORM_RANDOM; E12(s, cov->tsdim, sqrt(1.0 - x * x), e); } void Whittle(double *x, cov_model *cov, double *v) { *v = WM(*x, PisNULL(WM_NOTINV) || P0INT(WM_NOTINV) ? P0(WM_NU) : 1.0 / P0(WM_NU), 0.0); // printf("%f %f ", *x, *v); assert(!ISNAN(*v)); } void logWhittle(double *x, cov_model *cov, double *v, double *sign) { *v = logWM(*x, PisNULL(WM_NOTINV) || P0INT(WM_NOTINV) ? P0(WM_NU) : 1.0 / P0(WM_NU), 0.0); assert(!ISNA(*v)); *sign = 1.0; } void DWhittle(double *x, cov_model *cov, double *v) { *v =DWM(*x, PisNULL(WM_NOTINV) || P0INT(WM_NOTINV) ? P0(WM_NU) : 1.0 / P0(WM_NU), 0.0); } void DDWhittle(double *x, cov_model *cov, double *v) // check calling functions, like hyperbolic and gneiting if any changings !! { *v=DDWM(*x, PisNULL(WM_NOTINV) || P0INT(WM_NOTINV) ? P0(WM_NU) : 1.0 / P0(WM_NU), 0.0); } void D3Whittle(double *x, cov_model *cov, double *v) // check calling functions, like hyperbolic and gneiting if any changings !! { *v=D3WM(*x, PisNULL(WM_NOTINV) || P0INT(WM_NOTINV) ? P0(WM_NU) : 1.0 / P0(WM_NU), PisNULL(WM_NOTINV) ? 0.0 : SQRT2); } void D4Whittle(double *x, cov_model *cov, double *v) // check calling functions, like hyperbolic and gneiting if any changings !! { *v=D4WM(*x, PisNULL(WM_NOTINV) || P0INT(WM_NOTINV) ? P0(WM_NU) : 1.0 / P0(WM_NU), PisNULL(WM_NOTINV) ? 0.0 : SQRT2); } void InverseWhittle(double *x, cov_model *cov, double *v){ // printf("invwhi %f %f %f %d\n", *x, RF_NA, RF_NAN, RF_NA == RF_NAN); double nu = (PisNULL(WM_NOTINV) || P0INT(WM_NOTINV)) ? P0(WM_NU) : 1.0 / P0(WM_NU); *v = (*x == 0.05) ? 1.0 / ScaleWM(nu) : RF_NA; // printf("invwhi end %f %f %f\n", *x, *v, nu); } void TBM2Whittle(double *x, cov_model *cov, double *v) { double nu = P0(WM_NU); assert(PisNULL(WM_NOTINV)); if (nu == 0.5) TBM2exponential(x, cov, v); else BUG; } double densityWhittle(double *x, cov_model *cov) { return densityWM(x, cov, PisNULL(WM_NOTINV) ? 0.0 : SQRT2); } int initWhittle(cov_model *cov, storage *s) { if (cov->role == ROLE_GAUSS && cov->method==SpectralTBM) { if (PisNULL(WM_NU)) { spec_properties *cs = &(s->spec); if (cov->tsdim <= 2) return NOERROR; cs->density = densityWhittle; int err=search_metropolis(cov, s); return err; } else return initMatern(cov, s); } else ILLEGAL_ROLE; } void spectralWhittle(cov_model *cov, storage *S, double *e) { spectral_storage *s = &(S->Sspectral); /* see Yaglom ! */ if (PisNULL(WM_NOTINV)) { if (cov->tsdim <= 2) { double nu = P0(WM_NU); E12(s, cov->tsdim, sqrt(pow(1.0 - UNIFORM_RANDOM, -1.0 / nu) - 1.0), e); } else { metropolis(cov, S, e); } } else spectralMatern(cov, S, e); } void DrawMixWM(cov_model VARIABLE_IS_NOT_USED *cov, double *random) { // inv scale // V ~ F in PSgen *random = -0.25 / log(UNIFORM_RANDOM); } double LogMixDensW(double VARIABLE_IS_NOT_USED *x, double logV, cov_model *cov) { double nu=P0(WM_NU); return PisNULL(WM_NOTINV) ? (M_LN2 + 0.5 * logV) * (1.0 - nu) - 0.5 *lgammafn(nu) // - 0.25 / cov->mpp[DRAWMIX_V] - 2.0 * (LOG2 + logV) ) : RF_NA; /* !! */ } /* Whittle-Matern or Whittle or Besset */ /// only lower parts of the matrices, including the diagonals are used when estimating !! static bool Bi = !true; #define BInudiag 0 #define BInured 1 #define BInu 2 #define BIs 3 #define BIcdiag 4 #define BIrhored 5 #define BIc 6 #define BInotinvnu 7 //int zaehler = 0; /* Whittle-Matern or Whittle or Besset */ void biWM2basic(cov_model *cov, double *a, double *lg, double *aorig, double *nunew) { // !! nudiag, nured has priority over nu // !! cdiag, rhored has priority over c double factor, beta, gamma, tsq, t1sq, t2sq, inf, infQ, discr, alpha , a2[3], dim = (double) cov->tsdim, d2 = dim * 0.5, *nudiag = P(BInudiag), nured = P0(BInured), *nu = P(BInu), *c = P(BIc), *s = P(BIs), *cdiag = P(BIcdiag), rho = P0(BIrhored); int i, *notinvnu = PINT(BInotinvnu); nu[i11] = nudiag[0]; nu[i22] = nudiag[1]; nu[i21] = 0.5 * (nu[i11] + nu[i22]) * nured; for (i=0; i<3; i++) { aorig[i] = 1.0 / s[i]; if (Bi) print("%d %f %f \n", i, s[i], aorig[i]); } if (PisNULL(BInotinvnu)) { for (i=0; i<3; i++) { a[i] = aorig[i]; nunew[i] = nu[i]; } } else { if (!notinvnu[0]) for (i=0; i<3; i++) nu[i] = 1.0 / nu[i]; for (i=0; i<3; i++) { nunew[i] = nu[i] < MATERN_NU_THRES ? nu[i] : MATERN_NU_THRES; a[i] = aorig[i] * sqrt(2.0 * nunew[i]); } } // printf("A\n"); for (i=0; i<3; i++) { a2[i] = a[i] * a[i]; lg[i] = lgammafn(nunew[i]); } alpha = 2 * nunew[i21] - nunew[i11] - nunew[i22]; // **************** ACHTUNG !!!!! ********* // nicht gut, sollte in check einmal berechnet werden // dies wiederspricht aber der MLE Maximierung, da dann // neu berechnet werden muss; verlg. natsc und cutoff (wo es nicht // programmiert ist !!) // printf("B %f %f %f\n", nunew[i11] + d2, nunew[i22] + d2, nunew[i21] + d2); //printf("here 2\n"); factor = exp(lgammafn(nunew[i11] + d2) - lg[i11] + lgammafn(nunew[i22] + d2) - lg[i22] + 2.0 * (lg[i21] - lgammafn(nunew[i21] + d2) + nunew[i11] * log(a[i11]) + nunew[i22] *log(a[i22]) - 2.0 * nunew[i21] * log(a[i21])) ); // printf("C\n"); // alpha u^2 + beta u + gamma = 0 gamma = (2.0 * nunew[i21] + dim) * a2[i11] * a2[i22] - (nunew[i22] + d2) * a2[i11] * a2[i21] - (nunew[i11] + d2) * a2[i22] * a2[i21]; beta = (2.0 * nunew[i21] - nunew[i22] + d2) * a2[i11] + (2.0 * nunew[i21] - nunew[i11] + d2) * a2[i22] - (nunew[i11] + nunew[i22] + dim) * a2[i21]; if (Bi) print("%f %f %f %f %f\n" , 2.0 * nunew[i21], - nunew[i11], + d2 , a2[i22] , (nunew[i11] + nunew[i22] + dim) * a2[i22]); // if (Bi) print("\nalpha=%f beta=%f gamma=%f\n", alpha, beta, gamma); if (Bi) print("\nnu=%f %f %f, a2=%f %f %f\n", nunew[0], nunew[1], nunew[2], a2[0], a2[1], a2[2]); if (Bi) print("%d %f %f %f NU22 %f\n", i22, nu[0], nu[1], nu[2], nu[i22]); if (nured == 1.0) { // lin. eqn only t2sq = (beta == 0.0) ? 0.0 : -gamma / beta; if (t2sq < 0.0) t2sq = 0.0; t1sq = t2sq; } else { // quadratic eqn. discr = beta * beta - 4.0 * alpha * gamma; if (discr < 0.0) { t1sq = t2sq = 0.0; } else { discr = sqrt(discr); t1sq = (-beta + discr) / (2.0 * alpha); if (t1sq < 0.0) t1sq = 0.0; t2sq = (-beta - discr) / (2.0 * alpha); if (t2sq < 0.0) t2sq = 0.0; } } inf = nured == 1.0 ? 1.0 : RF_INF; // t^2 = infty ; nudiag[1]>1.0 not // allowed by definition for (i=0; i<3; i++) { tsq = (i == 0) ? 0.0 : (i == 1) ? t1sq : t2sq; // print("discr=%f a2[i22]=%f tsq=%f nu1=%f \ndim=%f a2[i11]=%f nu0=%f a2[i21]=%f nu3=%f d/2=%f\n",discr, // a2[i22], tsq, nunew[i21], dim, a2[i11], nunew[i11], a2[i21] , nunew[i22], d2); infQ = pow(a2[i21] + tsq, 2.0 * nunew[i21] + dim) / (pow(a2[i11] + tsq, nunew[i11] + d2) * pow(a2[i22] + tsq, nunew[i22] + d2)); if (infQ < inf) inf = infQ; } c[i11] = cdiag[0]; c[i22] = cdiag[1]; c[i21] = rho * sqrt(factor * inf * c[i11] * c[i22]); if (Bi) print("c=%f %f %f rho=%f %f %f\n", c[0], c[1],c[2], rho, factor, inf); Bi = false; } int initbiWM2(cov_model *cov, storage *stor) { double a[3], lg[3], aorig[3], nunew[3], *c = P(BIc), *cdiag = P(BIcdiag), *nu = P(BInu), *nudiag = P(BInudiag); bool check = stor->check; int i, *notinvnu = PINT(BInotinvnu); biwm_storage *S = cov->Sbiwm; assert(S != NULL); if (S->nudiag_given) { kdefault(cov, BInured, 1.0); if (check && !PisNULL(BInu)) { if (cov->nrow[BInu] != 3 || cov->ncol[BInu] != 1) QERRC(BInu, "'nu' must be a 3 x 1 vector"); if (fabs(nu[i11] - nudiag[0]) > nu[i11] * epsilon || fabs(nu[i22] - nudiag[1]) > nu[i22] * epsilon || fabs(nu[i21] - 0.5 * (nudiag[i11] + nudiag[1]) * P0(BInured)) > nu[i21] * epsilon) { //PMI(cov); QERRC(BInu, "'nu' does not match 'nudiag' and 'nured12'."); } } else { if (PisNULL(BInu)) PALLOC(BInu, 3, 1); nu = P(BInu); nu[i11] = nudiag[0]; nu[i22] = nudiag[1]; nu[i21] = 0.5 * (nu[i11] + nu[i22]) * P0(BInured); } } else { if (check && !PisNULL(BInured)) QERRC(BInured, "'nured12' may not be set if 'nu' is given"); if (PisNULL(BInu)) QERRC(BInu, "either 'nu' or 'nured12' must be set"); if (PisNULL(BInudiag)) PALLOC(BInudiag, 2, 1); nudiag = P(BInudiag); nudiag[0] = nu[i11]; /// nudiag[1] = nu[i22]; if (PisNULL(BInured)) PALLOC(BInured, 1, 1); P(BInured)[0] = nu[i21] / (0.5 * (nudiag[i11] + nudiag[1])); } if (!PisNULL(BInotinvnu) && !notinvnu[0]) for (i=0; i<3; i++) nu[i] = 1.0 / nu[i]; cov->full_derivs = cov->rese_derivs = 1; // kann auf 2 erhoeht werden, falls programmiert for (i=0; i<3; i++) { int derivs = (int) (nu[i] - 1.0); if (cov->full_derivs < derivs) cov->full_derivs = derivs; } if (PisNULL(BIs)) { PALLOC(BIs, 3, 1); double *s = P(BIs); for (i=0; i<3; s[i++] = 1.0); } if (S->cdiag_given) { if (PisNULL(BIrhored)) QERRC(BIrhored, "'cdiag' and 'rhored' must be set"); if (check && !PisNULL(BIc)) { if (cov->nrow[BIc] != 3 || cov->ncol[BIc] != 1) QERRC(BIc, "'c' must be a 3 x 1 vector"); if (fabs(c[i11] - cdiag[0]) > c[i11] * epsilon || fabs(c[i22] - cdiag[1]) > c[i22] * epsilon ) { // printf("c %f %f %f %f diff=%e eps=%e diff1=%e eps=%e\n", //c[i11], c[i22], cdiag[0], cdiag[1], // c[i11] - cdiag[0], c[i11] * epsilon, // c[i22] - cdiag[1], c[i22] * epsilon ); QERRC(BIc, "'c' does not match 'cdiag'."); } double savec12 = c[i21]; biWM2basic(cov, a, lg, aorig, nunew); // // PMI(cov); //print("cc c=%f save=%f wpa=%e abs=%e c.eps=%e %d\n", // c[i21], savec12, epsilon, fabs(c[i21] - savec12), c[i21] * epsilon, // fabs(c[i21] - savec12) > fabs(c[i21]) * epsilon); if (fabs(c[i21] - savec12) > fabs(c[i21]) * epsilon) QERRC(BIc, "'c' does not match 'rhored'."); } else { if (PisNULL(BIc)) PALLOC(BIc, 3, 1); c = P(BIc); biWM2basic(cov, a, lg, aorig, nunew); } } else { if (check && !PisNULL(BIrhored)) QERRC(BIrhored, "'rhored' may not be set if 'cdiag' is not given"); if (PisNULL(BIc)) QERRC(BIc, "either 'c' or 'cdiag' must be set"); if (!ISNAN(c[i11]) && !ISNAN(c[i22]) && (c[i11] < 0.0 || c[i22] < 0.0)) QERRC(BIc, "variance parameter c[0], c[2] must be non-negative."); if (PisNULL(BIcdiag)) PALLOC(BIcdiag, 2, 1); if (PisNULL(BIrhored)) PALLOC(BIrhored, 1, 1); cdiag = P(BIcdiag); cdiag[0] = c[i11]; cdiag[1] = c[i22]; double savec1 = c[i21]; if (savec1 == 0.0) P(BIrhored)[0] = 0.0; // wichtig falls c[0] oder c[2]=NA else { P(BIrhored)[0] = 1.0; biWM2basic(cov, a, lg, aorig, nunew); P(BIrhored)[0] = savec1 / c[i21]; } } biWM2basic(cov, S->a, S->lg, S->aorig, S->nunew); //PMI(cov); cov->initialised = true; return NOERROR; } void kappa_biWM(int i, cov_model *cov, int *nr, int *nc){ *nc = *nr = i < CovList[cov->nr].kappas ? 1 : -1; if (i==BInudiag || i==BIcdiag) *nr = 2; else if (i==BInu || i==BIs || i==BIc) *nr = 3; } void biWM2(double *x, cov_model *cov, double *v) { int i; double *c = P(BIc), *nu = P(BInu), xx = *x; biwm_storage *S = cov->Sbiwm; // if (S==NULL) {APMI(cov);} else printf("S not NULL "); assert(S != NULL); assert(cov->initialised); for (i=0; i<3; i++) { v[i] = c[i] * WM(fabs(S->a[i] * xx), S->nunew[i], 0.0); if (!PisNULL(BInotinvnu) && nu[i] > MATERN_NU_THRES) { double w, y; y = fabs(S->aorig[i] * xx * INVSQRTTWO); Gauss(&y, cov, &w); *v = *v * MATERN_NU_THRES / nu[i] + (1 - MATERN_NU_THRES / nu[i]) * w; } } v[3] = v[i22]; v[2] = v[i21]; // assert(false); } void biWM2D(double *x, cov_model *cov, double *v) { int i; double *c = P(BIc), *nu = P(BInu), xx = *x; biwm_storage *S = cov->Sbiwm; assert(S != NULL); assert(cov->initialised); for (i=0; i<3; i++) { v[i] = c[i] * S->a[i] * DWM(fabs(S->a[i] * xx), S->nunew[i], 0.0); if (!PisNULL(BInotinvnu) && nu[i] > MATERN_NU_THRES) { double w, y, scale = S->aorig[i] * INVSQRTTWO; y = fabs(scale * xx); DGauss(&y, cov, &w); w *= scale; *v = *v * MATERN_NU_THRES / nu[i] + (1 - MATERN_NU_THRES / nu[i]) * w; } } v[3] = v[i22]; v[2] = v[i21]; } int checkbiWM2(cov_model *cov) { // !! nudiag, nured has priority over nu // !! cdiag, rhored has priority over c int err; storage s; STORAGE_NULL(&s); s.check = true; assert(PisNULL(BIrhored) || ISNAN(P0(BIrhored)) || P0(BIrhored) <= 1); //kdefault(cov, 5, 1); // if ((err = checkkappas(cov, false)) != NOERROR) return err; if (cov->Sbiwm == NULL) { cov->Sbiwm = (biwm_storage*) MALLOC(sizeof(biwm_storage)); BIWM_NULL(cov->Sbiwm); } biwm_storage *S = cov->Sbiwm; assert(S != NULL); S->nudiag_given = !PisNULL(BInudiag); S->cdiag_given = !PisNULL(BIcdiag); if ((err=initbiWM2(cov, &s)) != NOERROR) return err; cov->vdim2[0] = cov->vdim2[1] = 2; return NOERROR; } sortsofparam paramtype_biWM(int k, int VARIABLE_IS_NOT_USED row, int VARIABLE_IS_NOT_USED col) { return ( k== BInudiag || k==BInured) ? CRITICALPARAM : (k == BInu || k == BIc) ? DONOTRETURNPARAM : (k == BIs) ? SCALEPARAM : ( k == BIcdiag) ? VARPARAM : ANYPARAM; // c ignored } void rangebiWM2(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ // kappanames("nu", REALSXP, "a", REALSXP, "c", REALSXP); // *nudiag = P0(BInudiag], range->min[BInudiag] = 0.0; range->max[BInudiag] = RF_INF; range->pmin[BInudiag] = 1e-1; range->pmax[BInudiag] = 4.0; range->openmin[BInudiag] = true; range->openmax[BInudiag] = true; // *nured12 = P0(BInured], range->min[BInured] = 1; range->max[BInured] = RF_INF; range->pmin[BInured] = 1; range->pmax[BInured] = 5; range->openmin[BInured] = false; range->openmax[BInured] = true; // *nu = P0(BInu], range->min[BInu] = 0.0; range->max[BInu] = RF_INF; range->pmin[BInu] = 1e-1; range->pmax[BInu] = 4.0; range->openmin[BInu] = true; range->openmax[BInu] = true; // s = P0(BIs], range->min[BIs] = 0.0; range->max[BIs] = RF_INF; range->pmin[BIs] = 1e-2; range->pmax[BIs] = 100.0; range->openmin[BIs] = true; range->openmax[BIs] = true; // *cdiag = P0(BIcdiag]; range->min[BIcdiag] = 0; range->max[BIcdiag] = RF_INF; range->pmin[BIcdiag] = 0.001; range->pmax[BIcdiag] = 1000; range->openmin[BIcdiag] = false; range->openmax[BIcdiag] = true; // *rho = P0(BIrhored]; range->min[BIrhored] = -1; range->max[BIrhored] = 1; range->pmin[BIrhored] = -0.99; range->pmax[BIrhored] = 0.99; range->openmin[BIrhored] = false; range->openmax[BIrhored] = false; // *c = P0(BIc]; range->min[BIc] = -RF_INF; range->max[BIc] = RF_INF; range->pmin[BIc] = 0.001; range->pmax[BIc] = 1000; range->openmin[BIc] = false; range->openmax[BIc] = true; // *notinvnu = P0(BInotinvnu]; range->min[BInotinvnu] = 0; range->max[BInotinvnu] = 1; range->pmin[BInotinvnu] = 0; range->pmax[BInotinvnu] = 1; range->openmin[BInotinvnu] = false; range->openmax[BInotinvnu] = false; } /////////// PARS WM /* Whittle-Matern or Whittle or Besset */ /// only lower parts of the matrices, including the diagonals are used when estimating !! #define PARSnudiag 0 void kappa_parsWM(int i, cov_model VARIABLE_IS_NOT_USED *cov, int *nr, int *nc){ if (i==PARSnudiag) { *nr = 0; *nc = 1; } else *nc = *nr = -1; } void parsWMbasic(cov_model *cov) { // !! nudiag, nured has priority over nu // !! cdiag, rhored has priority over c double dim = (double) cov->tsdim, d2 = dim * 0.5, *nudiag = P(PARSnudiag); int i, j, vdiag, vdim = cov->nrow[PARSnudiag], // hier noch nicht cov->vdim, falls parsWMbasic von check aufgerufen wird, und cov->vdim noch nicht gesetzt ist vdimP1 = vdim + 1; // **************** ACHTUNG !!!!! ********* // nicht gut, sollte in check einmal berechnet werden // dies wiederspricht aber der MLE Maximierung, da dann // neu berechnet werden muss; verlg. natsc und cutoff (wo es nicht // programmiert ist !!) // printf("in\n"); for (vdiag=i=0; iq[vdiag] = 1.0; for (j=i+1; jq[idx] = cov->q[vdiag + vdim * (j-i)] = exp(0.5 * (lgammafn(nudiag[i] + d2) + lgammafn(nudiag[j] + d2) - lgammafn(nudiag[i]) - lgammafn(nudiag[j]) + 2.0 * (lgammafn(half) - lgammafn(half + d2)) )); // printf("idx = %d %d %d %f\n", idx, i, j, cov->q[0]); } } // printf("out\n"); } void parsWM(double *x, cov_model *cov, double *v) { int i, j, vdiag, vdim = cov->vdim2[0], vdimP1 = vdim + 1; double *nudiag = P(PARSnudiag); parsWMbasic(cov); for (vdiag=i=0; iq[idx]; // printf("v=%f %d %d %f half=%f %f\n", v[idx], idx,vdiag + vdim * (j-i), // WM(*x, half, 0.0), half, cov->q[idx]); } } //printf("x=%f %f\n", *x, v[0]); } void parsWMD(double *x, cov_model *cov, double *v) { int i, j, vdiag, vdim = cov->vdim2[0], vdimP1 = vdim + 1; double *nudiag = P(PARSnudiag); parsWMbasic(cov); for (vdiag=i=0; iq[idx]; } } } int checkparsWM(cov_model *cov) { double *nudiag = P(PARSnudiag); int i, err, vdim = cov->nrow[PARSnudiag], // vdimP1 = vdim + 1, vdimSq = vdim * vdim; cov->vdim2[0] = cov->vdim2[1] = vdim; if (vdim == 0) SERR("'nudiag' not given"); if ((err = checkkappas(cov, true)) != NOERROR) return err; cov->qlen = vdimSq; if (cov->q == NULL) cov->q = (double*) CALLOC(sizeof(double), cov->qlen); // printf("vdimSq = %d\n", vdimSq); cov->full_derivs = cov->rese_derivs = 1; for (i=0; ifull_derivs < derivs) cov->full_derivs = derivs; } /* #define dummyN 5 * ParsWMMaxVDim double value[ParsWMMaxVDim], ivalue[ParsWMMaxVDim], dummy[dummyN], min = RF_INF; int j, ndummy = dummyN; */ // APMI(cov); return NOERROR; } sortsofparam paramtype_parsWM(int k, int VARIABLE_IS_NOT_USED row, int VARIABLE_IS_NOT_USED col) { return ( k== PARSnudiag) ? CRITICALPARAM : ANYPARAM; // c ignored } void rangeparsWM(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ // kappanames("nu", REALSXP, "a", REALSXP, "c", REALSXP); // *nudiag = P0(PARSnudiag], range->min[PARSnudiag] = 0.0; range->max[PARSnudiag] = RF_INF; range->pmin[PARSnudiag] = 1e-1; range->pmax[PARSnudiag] = 4.0; range->openmin[PARSnudiag] = true; range->openmax[PARSnudiag] = true; } //void Nonestat(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v){ // v[0] = RF_INF;} //void Nonenonstat(double *x, double *y, cov_model VARIABLE_IS_NOT_USED *cov, double *v){ // v[0] = RF_INF;} //void rangeNone(cov_model VARIABLE_IS_NOT_USED *cov, range_type VARIABLE_IS_NOT_USED *range){ } ////////////////////////////////////// NOT A COVARIANCE FCT double SurfaceSphere(int d, double r) { // d = Hausdorff-Dimension der Oberflaeche der Sphaere // NOT 2 \frac{\pi^{d/2}}{\Gamma(d/2)} r^{d-1}, // BUT 2 \frac{\pi^{(d+1)/2}}{\Gamma((d+1)/2)} r^{d}, double D = (double) d; // printf("r=%f, %f %f %f\n", r, D, pow(SQRTPI * r, D - 1.0), gammafn(0.5 * D)); return 2.0 * SQRTPI * pow(SQRTPI * r, D) / gammafn(0.5 * (D + 1.0)); } double VolumeBall(int d, double r) { // V_n(R) = \frac{\pi^{d/2}}{\Gamma(\frac{d}{2} + 1)}R^n, double D = (double) d; return pow(SQRTPI * r, D) / gammafn(0.5 * D + 1.0); } void ball(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v) { // isotropic function, expecting only distance; BALL_RADIUS=1.0 assert(*x >= 0); *v = (double) (*x <= BALL_RADIUS); } void Inverseball(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v){ *v = *x > 1.0 ? 0.0 : BALL_RADIUS; } int struct_ball(cov_model *cov, cov_model **newmodel){ assert(newmodel != NULL); if (hasMaxStableRole(cov)) { return addUnifModel(cov, BALL_RADIUS, newmodel); } else { //APMI(cov); ILLEGAL_ROLE; } return NOERROR; } int init_ball(cov_model *cov, storage VARIABLE_IS_NOT_USED *s) { assert(s != NULL); // printf("init ball\n"); APMI(cov); if (hasNoRole(cov)) return NOERROR; if (hasAnyShapeRole(cov)) { cov->mpp.maxheights[0] = 1.0; if (cov->mpp.moments >= 1) { cov->mpp.mM[1] = cov->mpp.mMplus[1] = VolumeBall(cov->tsdim, BALL_RADIUS); int i; for (i=2; i<=cov->mpp.moments; i++) cov->mpp.mM[i] = cov->mpp.mMplus[i] = cov->mpp.mM[1]; } } else ILLEGAL_ROLE; return NOERROR; } void do_ball(cov_model VARIABLE_IS_NOT_USED *cov, storage VARIABLE_IS_NOT_USED *s) { assert(s != NULL); // mppinfotype *info = &(s->mppinfo); // info->logdens = 0.0; //info->radius = cov->mpp.refradius; //info->sd = RF_NA; // printf("info = %f %f\n", safenfo->radius, info->sd); } /// Poisson polygons double meanVolPolygon(int dim, double beta) { double kd = VolumeBall(dim, 1.0), kdM1 = VolumeBall(dim-1, 1.0); return intpow(dim * kd / (kdM1 * beta), dim) / kd; } void Polygon(double *x, cov_model VARIABLE_IS_NOT_USED *cov, double *v) { polygon_storage *ps = cov->Spolygon; assert(ps != NULL); *v = (double) isInside(ps->P, x); } void Inversepolygon(double VARIABLE_IS_NOT_USED *x, cov_model *cov, double *v){ polygon_storage *ps = cov->Spolygon; int d, dim = cov->tsdim; if (ps == NULL) { *v = RF_NA; return; } polygon *P = ps->P; if (P != NULL) { double max = 0.0; for (d=0; dbox0[d]); if (y > max) max = y; y = fabs(P->box1[d]); if (y > max) max = y; } } else { BUG; *v = pow(meanVolPolygon(dim, P0(POLYGON_BETA)) / VolumeBall(dim, 1.0), 1.0/dim); // to do kann man noch mit factoren multiplizieren, siehe // strokorb/schlather, max // um unabhaengigkeit von der Dimension zu erlangen } } void InversepolygonNonstat(double VARIABLE_IS_NOT_USED *v, cov_model *cov, double *min, double *max){ polygon_storage *ps = cov->Spolygon; int d, dim = cov->tsdim; assert(ps != NULL); if (ps == NULL) { for (d=0; dP; if (P != NULL) { for (d=0; dbox0[d]; max[d] = P->box1[d]; // printf("d=%d %f %f\n", d, P->box0[d], P->box1[d]); } } else { // gibt aquivalenzradius eines "mittleres" Polygon zurueck BUG; double size = pow(meanVolPolygon(dim, P0(POLYGON_BETA)) / VolumeBall(dim, 1.0), 1.0/dim); // to do kann man noch mit factoren multiplizieren, siehe // strokorb/schlather, max-stabile Modelle mit gleichen tcf for (d=0; dtsdim <= MAXDIM_POLY); if (cov->tsdim != 2) SERR("random polygons only defined for 2 dimensions"); // to do assert(cov->tsdim == cov->xdimown); kdefault(cov, POLYGON_BETA, 1.0); if ((err = checkkappas(cov)) != NOERROR) return err; cov->deterministic = FALSE; return NOERROR; } void range_polygon(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[POLYGON_BETA] = 0; range->max[POLYGON_BETA] = RF_INF; range->pmin[POLYGON_BETA] = 1e-3; range->pmax[POLYGON_BETA] = 1e3; range->openmin[POLYGON_BETA] = true; range->openmax[POLYGON_BETA] = true; } int struct_polygon(cov_model VARIABLE_IS_NOT_USED *cov, cov_model VARIABLE_IS_NOT_USED **newmodel){ /* assert(newmodel != NULL); double beta = P0(POLYGON_BETA); if (hasAnyShapeRole(cov)) { double dim = cov->tsdim, safety = P0(POLYGON_SAFETY), // to do : zhou approach ! equiv_cube_length = pow(beta, -1.0/dim); return addUnifModel(cov, // to do : zhou approach ! 0.5 * equiv_cube_length * safety, newmodel); } else { //APMI(cov); ILLEGAL_ROLE; } */ BUG; return NOERROR; } polygon_storage *create_polygon() { polygon_storage *ps; if ((ps = (polygon_storage*) MALLOC(sizeof(polygon_storage))) == NULL) return NULL; if ((ps->P = (polygon*) MALLOC(sizeof(polygon))) == NULL) { free(ps); return NULL; } POLYGON_NULL(ps); return ps; } int init_polygon(cov_model *cov, storage VARIABLE_IS_NOT_USED *s) { int i, err, dim = cov->tsdim; double beta = P0(POLYGON_BETA), lambda = beta; // / VolumeBall(dim - 1, 1.0) * (dim * VolumeBall(dim, 1.0)); assert(s != NULL); // printf("init polygon\n"); APMI(cov) if (cov->Spolygon == NULL) { if ((cov->Spolygon = create_polygon()) ==NULL) return ERRORMEMORYALLOCATION; } // nicht nur aber auch zur Probe struct polygon_storage *ps = cov->Spolygon; assert(ps != NULL && ps->P != NULL); if (!false) { freePolygon(ps->P); if ((err=rPoissonPolygon(ps->P, lambda, true)) != NOERROR) SERR1("poisson polygon cannot be simulated (error=%d)", err); // printf("area = %f %f %f %f \n", getArea(ps->P), lambda, ps->P->box0[0], ps->P->box0[1]); } else { BUG; // valgrind memalloc loss ! + lange Laufzeiten ?! if ((err=rPoissonPolygon2(ps, lambda, true)) != NOERROR) SERR1("Poisson polygon cannot be simulated (error=%d)", err); } if (hasAnyShapeRole(cov)) { double c = meanVolPolygon(dim, beta); cov->mpp.maxheights[0] = 1.0; for (i=1; i<=cov->mpp.moments; i++) cov->mpp.mM[i] = cov->mpp.mMplus[i] = c; } else ILLEGAL_ROLE; return NOERROR; } #define USER_TYPE 0 #define USER_DOM 1 #define USER_ISO 2 #define USER_VDIM 3 #define USER_BETA 4 #define USER_VARIAB 5 #define USER_FCTN 6 #define USER_FST 7 #define USER_SND 8 #define USER_ENV 9 //#define USER_TRD 9 #define USER_LAST USER_ENV void evaluateUser(double *x, double *y, bool Time, cov_model *cov, sexp_type *which, double *Res) { SEXP res, env = PENV(USER_ENV)->sexp; int i, vdim = cov->vdim2[0] * cov->vdim2[1], ncol = cov->ncol[USER_BETA], n = cov->xdimown; double *beta = P(USER_BETA); assert(which != NULL); // error("tried to call a function not defined by the user or functionality not programmed yet"); // i = 0; REAL(xvec)[i] = (double) 1.23234; if (cov->nrow[USER_VARIAB] >= 2 && PINT(USER_VARIAB)[1] != -2) { if (Time) { addVariable( (char *) "T", x + (--n), 1, 1, env); } switch (n) { case 3 : addVariable( (char *) "z", x+2, 1, 1, env); case 2 : addVariable( (char *) "y", x+1, 1, 1, env); case 1 : addVariable( (char *) "x", x+0, 1, 1, env); break; default: BUG; } } else { // printf("n=%d %f %f\n", n, x[0], x[1]); assert(false); addVariable( (char *) "x", x, n, 1, env); if (y != NULL) addVariable( (char *) "y", y, n, 1, env); } res = eval(which->sexp, env); //printf("vdim = %d %f\n"; if (beta == NULL) { for (i=0; inr].kappas ? 1 : -1; if (i == USER_VDIM) *nr = SIZE_NOT_DETERMINED; if (i == USER_VARIAB) *nr=SIZE_NOT_DETERMINED; if (i == USER_BETA) *nr=*nc=SIZE_NOT_DETERMINED; } void User(double *x, cov_model *cov, double *v){ evaluateUser(x, NULL, Loc(cov)->Time, cov, PSEXP(USER_FCTN), v); } void UserNonStat(double *x, double *y, cov_model *cov, double *v){ // printf("nonstat\n"); evaluateUser(x, y, false, cov, PSEXP(USER_FCTN), v); } void DUser(double *x, cov_model *cov, double *v){ evaluateUser(x, NULL, Loc(cov)->Time, cov, PSEXP(USER_FST), v); } void DDUser(double *x, cov_model *cov, double *v){ evaluateUser(x, NULL, Loc(cov)->Time, cov, PSEXP(USER_SND), v); } //void D3User(double *x, cov_model *cov, double *v){ // assert(false); // unused // evaluateUser(x, cov->xdimown, USER_TRD, v); //} int checkUser(cov_model *cov){ cov_fct *C = CovList + cov->nr; kdefault(cov, USER_DOM, XONLY); if (PisNULL(USER_ISO)) { Types type = (Types) P0INT(USER_TYPE); if (isNegDef(type)) kdefault(cov, USER_ISO, ISOTROPIC); else if (isProcess(type) || isShape(type)) kdefault(cov, USER_ISO, CARTESIAN_COORD); else SERR1("type='%s' not allowed", TYPENAMES[type]); } int //*type = (int *) P0(USER_TYPE], *dom = PINT(USER_DOM), *iso = PINT(USER_ISO), *vdim =PINT(USER_VDIM); bool Time, fctn = !PisNULL(USER_FCTN), fst = !PisNULL(USER_FST), snd = !PisNULL(USER_SND); //trd = P0(USER_TRD] != NULL; int err, *nrow = cov->nrow, *variab = PINT(USER_VARIAB), //codierung variab=1:x, 2:y 3:z, 4:T nvar = cov->nrow[USER_VARIAB], *pref = cov->pref; //assert(false); if (nvar < 1) SERR("variables not of required form ('x', 'y', 'z', 'T')"); if (cov->domown != *dom) SERR2("wrong domain (requ=%d; provided=%d)", cov->domown, *dom); if (cov->isoown != *iso) SERR2("wrong isotropy assumption (requ=%d; provided=%d)", cov->isoown,*iso); if (PENV(USER_ENV) == NULL) BUG; if (!PisNULL(USER_BETA)) { if (vdim == NULL) kdefault(cov, USER_VDIM, nrow[USER_BETA]); else if (*vdim != nrow[USER_BETA]) SERR("number of columns of 'beta' does not equal 'vdim'"); cov->vdim2[0] = nrow[USER_BETA]; cov->vdim2[1] = 1; } else { if (PisNULL(USER_VDIM)) kdefault(cov, USER_VDIM, 1); cov->vdim2[0] = P0INT(USER_VDIM); cov->vdim2[1] = cov->nrow[USER_VDIM] == 1 ? 1 : PINT(USER_VDIM)[1]; } if (cov->nrow[USER_VDIM] > 2) SERR1("'%s' must be a scalar or a vector of length 2", KNAME(USER_VDIM)); if ((err = checkkappas(cov, false)) != NOERROR) return err; if (variab[0] != 1 && (variab[0] != 4 || nvar > 1)) SERR("'x' not given"); if (nvar > 1) { variab[1] = abs(variab[1]); // it is set to its negativ value // below, when a kernel is defined if (variab[1] == 3) SERR("'z' given but not 'y'"); } Time = variab[nvar-1] == 4; if (((nvar >= 3 || variab[nvar-1] == 4) && (!ISNA(GLOBAL.coords.xyz_notation) && !GLOBAL.coords.xyz_notation)) // || // (nrow[USER_VARIAB] == 1 && !ISNA_INT(GLOBAL.coords.xyz_notation) // && GLOBAL.coords.xyz_notation) ) SERR("mismatch of indicated xyz-notation"); if (Time xor Loc(cov)->Time) SERR("If 'T' is given, it must be given both as coordinates and as variable 'T' in the function 'fctn'"); if ((nvar > 2 || (nvar == 2 && variab[1] != 2)) && cov->domown == KERNEL) SERR("'xyz_notation' not valid for anisotropic models"); if (nvar == 2 && variab[1] == 2) { // sowohl nonstat also auch x, y Schreibweise moeglich if (ISNA(GLOBAL.coords.xyz_notation)) SERR("'xyz_notation' equals 'NA', but should be a logical value."); if (cov->domown == KERNEL && GLOBAL.coords.xyz_notation==2) // RFcov SERR("'xyz_notation' is not valid for anisotropic models"); } if (nvar > 1) { if (cov->domown == XONLY) { if (cov->isoown == ISOTROPIC) { SERR("two many variables given for motion invariant function"); } else if (cov->isoown == SPACEISOTROPIC && nvar != 2) SERR("number of variables does not match a space-isotropic model"); } else { if (nvar == 2 && variab[1] == 2) variab[1] = -2;//i.e. non domain (kernel) } } if (!ISNA(GLOBAL.coords.xyz_notation)) { // PMI(cov, "xxxxx"); //printf("glob %d\n", GLOBAL.coords.xyz_notation); // printf("%d\n", cov->domown); // printf("%d\n", nvar); // printf("%d\n", variab[0]); if ((GLOBAL.coords.xyz_notation == 2 && cov->domown == KERNEL) || ((nvar > 2 || (nvar == 2 && cov->domown==XONLY)) && variab[1] == -2)) { // printf("variab[1]=%d\n", variab[1]); SERR("domain assumption, model and coordinates do not match."); } } if ((cov->xdimown == 4 && !Loc(cov)->Time) || cov->xdimown > 4) SERR("Notation using 'x', 'y', 'z' and 'T' allows only for 3 spatial dimensions and an additional time component."); if (fctn) { C->F_derivs = C->RS_derivs = 0; pref[Direct] = pref[Sequential] = pref[CircEmbed] = pref[Nothing] = 5; if (fst) { C->F_derivs = C->RS_derivs = 1; pref[TBM] = 5; if (snd) { C->F_derivs = C->RS_derivs = 2; //if (trd) { // C->F_derivs = C->RS_derivs = 3; // } //} else { // ! snd //if (trd) SERR("'trd' given but not 'snd'"); } } else { // !fst if (snd) SERR("'snd' or 'trd' given but not 'fst'"); } } else { // !fctn if (fst || snd) SERR("'fst' or 'snd' or 'trd' given but not 'fctn'"); } // APMI(cov); return NOERROR; } bool TypeUser(Types required, cov_model *cov) { int *type = PINT(USER_TYPE); if (type == NULL) return false; if (!isShape((Types) type[0])) return false; // SERR3("currently, only the types '%s', '%s' and '%s' are allowed.", // TYPENAMES[PosDefType], TYPENAMES[NegDefType], TYPENAMES[ShapeType]); return TypeConsistency(required, (Types) type[0]); } void rangeUser(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[USER_TYPE] = TcfType; range->max[USER_TYPE] = TrendType; range->pmin[USER_TYPE] = TcfType; range->pmax[USER_TYPE] = TrendType; range->openmin[USER_TYPE] = false; range->openmax[USER_TYPE] = false; range->min[USER_DOM] = XONLY; range->max[USER_DOM] = KERNEL; range->pmin[USER_DOM] = XONLY; range->pmax[USER_DOM] = KERNEL; range->openmin[USER_DOM] = false; range->openmax[USER_DOM] = false; range->min[USER_ISO] = ISOTROPIC; range->max[USER_ISO] = CARTESIAN_COORD; range->pmin[USER_ISO] = ISOTROPIC; range->pmax[USER_ISO] = CARTESIAN_COORD; range->openmin[USER_ISO] = false; range->openmax[USER_ISO] = false; range->min[USER_VDIM] = 1; range->max[USER_VDIM] = INFDIM; range->pmin[USER_VDIM] = 1; range->pmax[USER_VDIM] = 10; range->openmin[USER_VDIM] = false; range->openmax[USER_VDIM] = true; range->min[USER_BETA] = RF_NEGINF; range->max[USER_BETA] = RF_INF; range->pmin[USER_BETA] = -1e5; range->pmax[USER_BETA] = 1e5; range->openmin[USER_BETA] = true; range->openmax[USER_BETA] = true; range->min[USER_VARIAB] = -2; range->max[USER_VARIAB] = 4; range->pmin[USER_VARIAB] = 1; range->pmax[USER_VARIAB] = 4; range->openmin[USER_VARIAB] = false; range->openmax[USER_VARIAB] = false; } // Sigma(x) = diag>0 + A'xx'A void kappa_Angle(int i, cov_model *cov, int *nr, int *nc){ int dim = cov->xdimown; *nr = i == ANGLE_DIAG ? dim : dim-1; *nc = i <= ANGLE_DIAG ? dim-1 : -1; } void Angle(double *x, cov_model *cov, double *v) { /// to do: extend to 3D! double A[9], c = cos(P0(ANGLE_ANGLE)), s = sin(P0(ANGLE_ANGLE)), *diag = P(ANGLE_DIAG); A[0] = c; A[1] = s; A[2] = -s; A[3] = c; if (diag!= NULL) { A[0] *= diag[0]; A[1] *= diag[1]; A[2] *= diag[0]; A[3] *= diag[1]; } else { double ratio = 1.0 / P0(ANGLE_RATIO); A[1] *= ratio; A[3] *= ratio; } v[0] = A[0] * x[0] + A[2] * x[1]; v[1] = A[1] * x[0] + A[3] * x[1]; // printf("%f %f %f %f\n", A[0], A[1], A[2], A[3], v[0], v[1]); //0.000000 2.500000 -1.000000 0.000000 //0.707107 0.176777 -0.707107 0.176777 // assert(false); } void invAngle(double *x, cov_model *cov, double *v) { /// to do: extend to 3D! double A[9], c = cos(P0(ANGLE_ANGLE)), s = sin(P0(ANGLE_ANGLE)), *diag = P(ANGLE_DIAG); if (x[0] == RF_INF && x[1] == RF_INF) { v[0] = v[1] = RF_INF; return; } if (x[0] == RF_NEGINF && x[1] == RF_NEGINF) { v[0] = v[1] = RF_NEGINF; return; } A[0] = c; A[1] = -s; A[2] = s; A[3] = c; if (diag!= NULL) { A[0] /= diag[0]; A[1] /= diag[0]; A[2] /= diag[1]; A[3] /= diag[1]; } else { double ratio = P0(ANGLE_RATIO); A[2] *= ratio; A[3] *= ratio; } v[0] = A[0] * x[0] + A[2] * x[1]; v[1] = A[1] * x[0] + A[3] * x[1]; // printf("%f %f %f %f\n", A[0], A[1], A[2], A[3], v[0], v[1]); // assert(false); } int checkAngle(cov_model *cov){ // int err; // pref_type pref = // {5, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 5}; // CE CO CI TBM Sp di sq Ma av n mpp Hy any // MEMCOPY(cov->pref, pref, sizeof(pref_type)); if (PisNULL(ANGLE_DIAG)) kdefault(cov, ANGLE_RATIO, 1.0); else if (!PisNULL(ANGLE_RATIO)) SERR2("'%s' and '%s' may not given at the same time", CovList[cov->nr].kappanames[ANGLE_RATIO], CovList[cov->nr].kappanames[ANGLE_DIAG]); cov->mpp.maxheights[0] = RF_NA; cov->matrix_indep_of_x = true; cov->vdim2[0] = 2; cov->vdim2[1] = 1; return NOERROR; } void rangeAngle(cov_model VARIABLE_IS_NOT_USED *cov, range_type* range){ range->min[ANGLE_ANGLE] = 0.0; range->max[ANGLE_ANGLE] = TWOPI; range->pmin[ANGLE_ANGLE] = 0.0; range->pmax[ANGLE_ANGLE] = TWOPI; range->openmin[ANGLE_ANGLE] = false; range->openmax[ANGLE_ANGLE] = true; range->min[ANGLE_RATIO] = 0; range->max[ANGLE_RATIO] = RF_INF; range->pmin[ANGLE_RATIO] = 1e-5; range->pmax[ANGLE_RATIO] = 1e5; range->openmin[ANGLE_RATIO] = false; range->openmax[ANGLE_RATIO] = true; range->min[ANGLE_DIAG] = 0; range->max[ANGLE_DIAG] = RF_INF; range->pmin[ANGLE_DIAG] = 1e-5; range->pmax[ANGLE_DIAG] = 1e5; range->openmin[ANGLE_DIAG] = false; range->openmax[ANGLE_DIAG] = true; } #define IDCOORD_ISO 0 void idcoord(double *x, cov_model *cov, double *v){ assert(P0INT(IDCOORD_ISO) == cov->isoown); int d, vdim = cov->vdim2[0]; // PMI(cov->calling); for (d=0; dvdim2[0], cov->vdim2[1], cov->vdim, d); // printf("%f\n", x[d]); v[d]=x[d]; } } int checkidcoord(cov_model *cov){ kdefault(cov, IDCOORD_ISO, ISOTROPIC); if (cov->isoown != P0INT(IDCOORD_ISO)) return ERRORINCORRECTSTATISO; cov->vdim2[0] = cov->xdimown; cov->vdim2[1] = 1; return NOERROR; } void rangeidcoord(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[IDCOORD_ISO] = ISOTROPIC; range->max[IDCOORD_ISO] = CYLINDER_COORD; range->pmin[IDCOORD_ISO] = ISOTROPIC; range->pmax[IDCOORD_ISO] = CYLINDER_COORD; range->openmin[IDCOORD_ISO] = false; range->openmax[IDCOORD_ISO] = false; } #define NULL_TYPE 0 void NullModel(double VARIABLE_IS_NOT_USED *x, cov_model VARIABLE_IS_NOT_USED *cov, double VARIABLE_IS_NOT_USED *v){ return; } void logNullModel(double VARIABLE_IS_NOT_USED *x, cov_model VARIABLE_IS_NOT_USED *cov, double VARIABLE_IS_NOT_USED *v, int VARIABLE_IS_NOT_USED *sign){ return; } bool TypeNullModel(Types required, cov_model *cov) { Types type = (Types) P0INT(NULL_TYPE); return TypeConsistency(required, type); } void rangeNullModel(cov_model VARIABLE_IS_NOT_USED *cov, range_type *range){ range->min[NULL_TYPE] = TcfType; range->max[NULL_TYPE] = OtherType; range->pmin[NULL_TYPE] = TcfType; range->pmax[NULL_TYPE] = OtherType; range->openmin[NULL_TYPE] = false; range->openmax[NULL_TYPE] = false; }