/* Authors Martin Schlather, martin.schlather@math.uni-goettingen.de Definition of correlation functions and derivatives of hypermodels Copyright (C) 2005 -- 2011 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "RF.h" #include "Covariance.h" #include #include // ------- end internal functions void co(double *x, cov_model *cov, double *v) { cov_model *next = cov->sub[0]; double y=*x, *q=cov->q, diameter = cov->p[pLOC_DIAM][0], a = cov->p[pLOC_A][0]; if (y <= diameter) CovList[next->nr].cov(x, next, v); else { *v = (y >= q[LOCAL_R]) ? 0.0 : q[CUTOFF_B] * pow(q[CUTOFF_ASQRTR] - pow(y, a), 2.0 * a); } } bool alternativeparam_co(cov_model *cov){ return false; } void range_co(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges; range->min[0] = 0.0; // CUTOFF_DIAM range->max[0] = RF_INF; range->pmin[0] = 1e-10; range->pmax[0] = 1e10; range->openmin[0] = true; range->openmax[0] = true; range->min[1] = 0.0; // cutoff_a range->max[1] = RF_INF; range->pmin[1] = 0.5; range->pmax[1] = 2.0; range->openmin[1] = true; range->openmax[1] = true; } int check_local(cov_model *cov, SimulationType type, int maxq, getlocalparam init, // next->coinit set_local_q_type set_local) { int i, err=NOERROR, msg; // timespacedim -- needed ?; double *q, q2[LOCAL_MAX], d=RF_NAN, **p = cov->p; cov_model *next = cov->sub[0], *truenext = next->sub[0]; localinfotype li; cov_fct *C; cov->qlen = maxq; // checkkappas(cov) is not called, but checked directly !! if ((err = check2X(next, cov->tsdim, 1, type == CircEmbedCutoff ? STATIONARY : VARIOGRAM, ISOTROPIC, UNIVARIATE)) != NOERROR) return err; next->tsdim = DEL_COV; // setbackward(cov, next); if (next->maxdim < cov->maxdim) cov->maxdim = next->maxdim; cov->manipulating_x=true; cov->normalmix = false; // cov->finiterange = true by default cov->diag &= next->diag; // cov->quasidiag &= next->quasidiag; cov->separatelast &= next->separatelast; cov->semiseparatelast &= next->semiseparatelast; // cov->variogram = false; // no changing in pref by submodel !! if (cov->q != NULL) { free(cov->q); // PrintModelInfo(cov); // ERR("q not NULL in check_local -- ask author"); } q = cov->q = (double*) malloc(maxq * sizeof(double)); for (i = 0; i < maxq; i++) q2[i] = RF_NAN; // q2 will be copied to cov->q; // {int i; printf("%d %f\n", cov->qlen); for(i=0;i<9;i++)printf("%f ", cov->q[i]); printf("\n"); assert(false);} C = CovList + truenext->nr; // next is GATTER only if (p[pLOC_DIAM] == NULL) { ERR("Diameter must always be given"); // cov->p[pLOC_DIAM] = (double*) malloc(sizeof(double)); // cov->ncol[0] = cov->nrow[0] = 1; // cov->p[pLOC_DIAM][0] = d = GetScaledDiameter(cov); } else { if (cov->ncol[pLOC_DIAM] != 1 || cov->nrow[pLOC_DIAM] != 1) ERR("diameter must be a scale"); d = cov->p[pLOC_DIAM][0]; } if (p[pLOC_A] == NULL) { if (C->implemented[type]) { int i; assert(init != NULL); // PrintModelInfo(truenext); init(truenext, &li); if (li.instances == 0) { ERR("parameter values do not allow for finding second parameter"); } cov->p[pLOC_A] = (double*) malloc(sizeof(double)); cov->ncol[pLOC_A] = cov->nrow[pLOC_A] = 1; q[LOCAL_R] = R_PosInf; // printf("%f\n", d); assert(false); msg = MSGLOCAL_FAILED; for (i=0; ip[pLOC_A][0] = li.value[i]; // co: a; ie: rawr } } } cov->q[LOCAL_MSG] = msg; if (msg == MSGLOCAL_FAILED) err = ERRORFAILED; } else { // PRINTF("%s\n", C->name); ERR("2nd parameter is neither given nor can be found automatically"); } } else { if (cov->ncol[pLOC_A] != 1 || cov->nrow[pLOC_A] != 1) ERR("`a' must be a scale"); err = set_local(truenext, cov->p[pLOC_A][0], d, q2); memcpy(q, q2, sizeof(double) * maxq); } // printf("pdq %f %f %f\n", cov->p[pLOC_A][0], d, q2); if (err != NOERROR) { XERR(err) // char Msg[255]; // errorMessage(err); // error(Msg); } return NOERROR; } int set_cutoff_q(cov_model *next, double a, double d, double *q) { double phi0, phi1, a2; //, one=1.0; a2 = a * a; cov_fct *C = CovList + next->nr; // PrintModelInfo(next); C->cov(&d, next, &phi0); C->D(&d, next, &phi1); phi1 *= d; if (phi0 <= 0.0) return MSGLOCAL_SIGNPHI; if (phi1 >= 0.0) return MSGLOCAL_SIGNPHIFST; // printf("check_co phi0=%f phi1=%f a=%f d=%f a2=%f\n", phi0, phi1, a, d, a2); // assert(false); // printf("p %f\n", phi1); // printf("a2 %f\n", a2); // printf("p0 %f\n", phi0); // printf("a %f\n", a); // printf("d %f\n", d); q[CUTOFF_B] =//sound qconstant even if variance of submodel is not 1 pow(- phi1 / (2.0 * a2 * phi0), 2.0 * a) * phi0 / pow(d, 2.0 * a2); // assert(false); q[CUTOFF_THEOR] = pow(1.0 - 2.0 * a2 * phi0 / phi1, 1.0 / a); q[LOCAL_R] = d * q[CUTOFF_THEOR]; q[CUTOFF_ASQRTR] = pow(q[LOCAL_R], a); // printf("phi0=%f %f %f %f\n", phi0, phi1, a, d); // printf("%f\n", d); assert(false); // printf("%f %f %f %f\n", q[CUTOFF_B], q[CUTOFF_THEOR], q[LOCAL_R], q[CUTOFF_ASQRTR]); //assert(false); return NOERROR; } int check_co(cov_model *cov) { cov_model *next = cov->sub[0]->sub[0];// sub[0] is GATTER ONLY cov_fct *C = CovList + next->nr; return check_local(cov, CircEmbedCutoff, CUTOFF_MAX, C->coinit, set_cutoff_q); } void Stein(double *x, cov_model *cov, double *v) { cov_model *next = cov->sub[0]; cov_fct *C = CovList + next->nr; double y=*x, z, *q=cov->q, diameter = cov->p[pLOC_DIAM][0]; if (y <= diameter) { C->cov(x, next, v); *v += q[INTRINSIC_A0] + q[INTRINSIC_A2] * y * y; // printf("%f %f %f %f %d %d \n ", // y, v[0], q[INTRINSIC_A0], q[INTRINSIC_A2], INTRINSIC_A0, INTRINSIC_A2); // PrintModelInfo(cov); // assert(v[0] < RF_INF); } else { z = q[LOCAL_R] - y; *v = (z <= 0.0) ? 0.0 : q[INTRINSIC_B] * z * z * z / y; } } bool alternativeparam_Stein(cov_model *cov) { cov->p[pLOC_A][0] *= 2.0; return true; } void range_Stein(cov_model *cov, range_arraytype* ra) { range_type *range = ra->ranges; range->min[0] = 0.0; // CUTOFF_DIAM range->max[0] = RF_INF; range->pmin[0] = 0.01; range->pmax[0] = 100; range->openmin[0] = true; range->openmax[0] = true; range->min[1] = 1.0; // stein_r range->max[1] = RF_INF; range->pmin[1] = 1.0; range->pmax[1] = 20.0; range->openmin[1] = false; range->openmax[1] = true; } int set_stein_q(cov_model *next, double r, double d, double *q) { double C0, phi0, phi1, phi2, zero = 0.0, rP1 = r + 1.0, rM1 = r - 1.0, dsq = d * d; cov_fct *C = CovList + next->nr; // printf("%ld %s\n", &zero, CovList[next->nr].name); // PrintModelInfo(next); C->cov(&zero, next, &C0); C->cov(&d, next, &phi0); C->D(&d, next, &phi1); // derivative of phi1 *= d; // scaled fctn at 1 C->D2(&d, next, &phi2); // 2nd derivative of phi2 *= dsq; // scaled fctn at 1 q[LOCAL_R] = r * d; q[INTRINSIC_A2] = (phi2 - phi1) / (3.0 * r * rP1) ; q[INTRINSIC_B] = (r == 1.0) ? 0.0 : q[INTRINSIC_A2] / (rM1 * dsq); q[INTRINSIC_A2] = (q[INTRINSIC_A2] - phi1 / 3.0 - phi2 / 6.0) / dsq; q[INTRINSIC_A0] = 0.5 * rM1 / rP1 * phi2 + phi1 / rP1 - phi0; // printf("check: %f %e r=%f intr:%f %f %f\n", // phi2, phi1, r, q[INTRINSIC_B], // q[INTRINSIC_A0], q[INTRINSIC_A2]); // assert(false); if ((q[INTRINSIC_B] < 0.0) || (q[INTRINSIC_A2] < 0.0) || (q[INTRINSIC_A0] + C0 < 0.0)) return MSGLOCAL_INITINTRINSIC; return NOERROR; } int check_Stein(cov_model *cov) { cov_model *next = cov->sub[0]->sub[0]; // dito cov_fct *C = CovList + next->nr; // printf("******************* check stein\n"); // PrintModelInfo(cov); // assert(false); return check_local(cov, CircEmbedIntrinsic, INTRINSIC_MAX, C->ieinit, set_stein_q); } void MaStein(double *x, cov_model *cov, double *v) { cov_model *next = cov->sub[0]; double nuG, gammas, **p = cov->p, v1, v2, nu = p[0][0], delta = p[1][0]; cov_fct *C = CovList + next->nr; C->cov(ZERO, next, &v1); C->cov(x + 1, next, &v2); nuG = nu + v1 + v2; if (nuG >= 80.0) { error("Whittle Matern function cannot be evaluated with parameter value b+g(t) greater than 80."); } gammas = lgammafn(nu + delta) - lgammafn(nu) -lgammafn(nuG + delta); double s = *x; *v = (s==0.0) ? exp(lgammafn(nuG) + gammas) : 2.0 * exp(nuG * log(0.5 * s) + gammas + log(bessel_k(s, nuG, 2.0)) - s); } int check_MaStein(cov_model *cov) { cov_model *next = cov->sub[0]; int err; if ((err = checkkappas(cov)) != NOERROR) return err; cov->normalmix = cov->finiterange = false; cov->manipulating_x=true; if ((err = check2X(next, cov->tsdim, cov->xdim, STATIONARY, ANISOTROPIC, UNIVARIATE)) != NOERROR) return err; if (cov->ncol[0] != 1 || cov->nrow[0] != 1) ERR("nu not scalar"); if (cov->ncol[1] != 1 || cov->nrow[1] != 1) ERR("d not scalar"); // if (cov->ncol[2] != 1 || cov->nrow[2] != cov->xdim - 1) { // sprintf(ERRORSTRING, "%s", // "dimension of vector V must be 1 less than the dim of the coordinates"); // return ERRORM; // } return NOERROR; // no setbackward ! } void range_MaStein(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges; range->min[0] = 0.0; // range->max[0] = RF_INF; range->pmin[0] = 1e-2; range->pmax[0] = 10.0; range->openmin[0] = true; range->openmax[0] = true; range->min[1] = 0.5 * (double) (cov->tsdim - 1); // d range->max[1] = RF_INF; range->pmin[1] = range->min[1]; range->pmax[1] = 10; range->openmin[1] = false; range->openmax[1] = true; } /* bivariate shift model */ void kappashift(int i, cov_model *cov, int *nr, int *nc){ *nc = 1; *nr = (i<=0) ? cov->tsdim : -1; } void shift(double *x, cov_model *cov, double *v) { cov_model *next = cov->sub[0]; cov_fct *C = CovList + next->nr; double y[ShiftMaxDim], *h = cov->p[0]; int i, dim = cov->tsdim; C->cov(x, next, v + 0); for (i=0; icov(y, next, v + 1); for (i=0; icov(y, next, v + 2); v[3] = v[0]; } int checkshift(cov_model *cov) { cov_model *next = cov->sub[0]; // cov_fct *C = CovList + next->nr; int err, dim = cov->tsdim; if (cov->xdim > ShiftMaxDim) { sprintf(ERRORSTRING, "For technical reasons max. dimension for ave is %d. Got %d.", StpMaxDim, cov->xdim); return ERRORMSG; } if ((err = checkkappas(cov)) != NOERROR) return err; cov->manipulating_x=true; cov->normalmix = cov->finiterange = false; if ((err = check2X(next, dim, dim, STATIONARY, (dim > 1) ? ANISOTROPIC : ISOTROPIC, UNIVARIATE)) != NOERROR) return err; setbackward(cov, next); return NOERROR; } void rangeshift(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges; range->min[0] = -RF_INF; range->max[0] = RF_INF; range->pmin[0] = -1000; range->pmax[0] = 1000; range->openmin[0] = true; range->openmax[0] = true; } /* Vector - Delta Delta^T */ void vector(double *x, cov_model *cov, double *v) { /* r = \| x\| d/d x_i f(r) = f'(r) x_i / r d^2/d x_i^2 f(r) = f''(r) x_i^2/r^2 + f'(r) (r^2 - x_i^2) / r^3 d^2/d x_i x_j f(r) = f''(r) x_i x_j/r^2 + f'(r) (- x_i x_j) / r^3 r = 0: d/d x_i f(r) |_0 = 0 d^2/d x_i^2 f(r) |_0 = f''(0) d^2/d x_i x_j f(r) = 0 Vector (n = dimension of spatial field) r=0 L = n * f''(0) operator: -0.5 * (a + 1) laplace + a * hessian, a in [-1,1]; a=1 */ cov_model *next = cov->sub[0]; cov_fct *N = CovList + next->nr; double norm[2], normSq0, normL2, normT2, D, D2, diag, a = cov->p[0][0], b = - 0.5 * (1.0 + a); int i, td = cov->tsdim, dim = ((int *)cov->p[1])[0], dimP1 = dim + 1, dimsq = dim * dim; normL2 = normT2 = 0.0; for (i=0; iisoIn == ISOTROPIC) { normSq0 = normL2 + normT2; } else { normSq0 = normL2; norm[1] = sqrt(normT2); } norm[0] = sqrt(normSq0); N->D(norm, next, &D); N->D2(norm, next, &D2); if (normSq0 == 0.0) { diag = (b * dim + a) * D2; for (i=0; isub[0]; cov_fct *N = CovList + next->nr; double *D, laplace, a = cov->p[0][0], b = - 0.5 * (1.0 + a); int i, j, k, endfor, dim = ((int *)cov->p[1])[0], dimP1 = dim + 1, dimsq = dim * dim, xdim = cov->tsdim, xdimsq = xdim * xdim, xdimP1 = xdim + 1, dimxdim = dim * xdim; D = (double*) malloc(sizeof(double) * xdimsq); //printf("%d %d\n", dim, xdim); assert(false); // should pass back the hessian N->hess(x, next, D); laplace = 0.0; // PrintModelInfo(next); // printf("return matrix %d\n", xdimsq); // for (i=0; i> %d %d %f %f %f\n", k, j, D[j], a, laplace ); v[k++] = D[j] * a; } } for (i=0; isub[0], *genuinenext = next->sub[0]; // cov_fct *N = CovList + next->sub[0]->nr; int err, dim = cov->tsdim; isotropy_type isotropy; cov->nr = VECTOR; // wegen nr++ unten; cov->normalmix = cov->finiterange = false; cov->manipulating_x=true; if ((err = check2X(next, dim, 1, STATIONARY, ISOTROPIC, UNIVARIATE)) != NOERROR) { // printf("err=%d\n", err); if ((err = check2X(next, dim, dim, STATIONARY, ZEROSPACEISO, UNIVARIATE)) != NOERROR) { // printf("err2=%d\n", err); if ((err = check2X(next, dim, dim, STATIONARY, ANISOTROPIC, UNIVARIATE)) != NOERROR) { // printf("err3=%d\n", err); return err; } } } assert(cov->xdim == cov->tsdim); if (genuinenext->derivatives < 2 && !genuinenext->hess) { // PrintModelInfo(cov); // printf("%s (%d): derivatives %d \n", CovList[genuinenext->nr].name, // genuinenext->nr, genuinenext->derivatives); // next is GATTER ERR("2nd derivative of submodel not defined (for the given paramters)"); } isotropy = next->isoIn; if (isotropy != ISOTROPIC && isotropy != SPACEISOTROPIC) { if (!genuinenext->hess) ERR("hess matrix not defined"); cov->nr++; } kdefault(cov, 0, 0.5); // a kdefault(cov, 1, (isotropy==SPACEISOTROPIC || isotropy==ZEROSPACEISO) ? dim - 1 : dim); // Dspace if ( (isotropy==SPACEISOTROPIC || isotropy==ZEROSPACEISO) && ((int*) (cov->p[1]))[0] != dim - 1) { // printf(".... %d %d\n", ((int*) (cov->p[1]))[0], dim); ERR("for spatiotemporal models 'vector' must be applied to spatial part"); } // PrintModelInfo(cov); setbackward(cov, next); cov->vdim = ((int*) (cov->p[1]))[0]; next->tsdim = DEL_COV; return NOERROR; } void rangevector(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges; range->min[0] = -1.0; range->max[0] = 1.0; range->pmin[0] = -1.0; range->pmax[0] = 1.0; range->openmin[0] = false; range->openmax[0] = false; range->min[1] = 1.0; range->max[1] = cov->tsdim; range->pmin[1] = 1.0; range->pmax[1] = cov->tsdim; range->openmin[1] = false; range->openmax[1] = false; } int zzz=0; /* Rot - Delta Delta^T */ void curl(double *x, cov_model *cov, double *v) { /* r = \| x\| d/d x_i f(r) = f'(r) x_i / r d^2/d x_i^2 f(r) = f''(r) x_i^2/r^2 + f'(r) (r^2 - x_i^2) / r^3 d^2/d x_i x_j f(r) = f''(r) x_i x_j/r^2 + f'(r) (- x_i x_j) / r^3 r = 0: d/d x_i f(r) |_0 = 0 d^2/d x_i^2 f(r) |_0 = f''(0) d^2/d x_i x_j f(r) = 0 Rot (n = dimension of spatial field) r=0 L = n * f''(0) operator: -0.5 * (a + 1) rot + a * hessian, a in [-1,1]; a=1/2 */ cov_model *next = cov->sub[0]; cov_fct *N = CovList + next->nr; double norm[2], normSq0, normL2, normT2, D, D2, D3, diag, a = -1.0, // curl free b = - 0.5 * (1.0 + a); int i, td = cov->tsdim, dim = td, // ((int *)cov->p[1])[0], // currently no space-time allowed -> BA thesis dimP1 = dim + 1, dimP2 = dim + 2, dimP3 = dim + 3, dimP2sqM1 = dimP2 * dimP2 -1; // for three dimensions much // more complicated normL2 = normT2 = 0.0; for (i=0; iisoIn == ISOTROPIC) { normSq0 = normL2 + normT2; } else { normSq0 = normL2; norm[1] = sqrt(normT2); } norm[0] = sqrt(normSq0); N->D(norm, next, &D); N->D2(norm, next, &D2); N->D3(norm, next, &D3); if (normSq0 == 0.0) { for (i=0; i<=dimP2sqM1; i++) v[i] = 0.0; N->cov(norm, next, v); // v[0] diag = (b * dim + a) * D2; for (i=dimP3; iD2(norm, next, v + dimP1); v[dimP1] *= 2.0; v[dimP2 * dimP1] = v[dimP1]; N->D4(norm, next, v + dimP2sqM1); v[dimP2sqM1] *= (8.0 / 3.0); } else { double z[2], D2nsq = D2 / normSq0, D1n = D / norm[0], D3n = D3 / norm[0], D1n3 = D / (norm[0] * normSq0), delta = a * (D2nsq - D1n3), div = b * ((D2nsq - D1n3) * normL2 + dim * D1n); int k,l; N->cov(norm, next, v); // v[0] z[0] = x[0]; z[1] = x[1]; for (i=1; i<=dim; i++) { // kante links und oben v[i] = -(v[i * dimP2] = z[i-1] * D1n); } diag = div + a * D1n; for (i= dimP3, k=0; kD4(norm, next, v + dimP2sqM1); // rechts unten v[dimP2sqM1] += 2.0 * D3n - D2nsq + D1n3; } // for (i=0; i<=15; i++) { // if (i!=15) v[i] = 0.0; // } } /* Div - Delta Delta^T */ void div(double *x, cov_model *cov, double *v) { // div -free !! /* r = \| x\| d/d x_i f(r) = f'(r) x_i / r d^2/d x_i^2 f(r) = f''(r) x_i^2/r^2 + f'(r) (r^2 - x_i^2) / r^3 d^2/d x_i x_j f(r) = f''(r) x_i x_j/r^2 + f'(r) (- x_i x_j) / r^3 r = 0: d/d x_i f(r) |_0 = 0 d^2/d x_i^2 f(r) |_0 = f''(0) d^2/d x_i x_j f(r) = 0 Div (n = dimension of spatial field) r=0 L = n * f''(0) operator: -0.5 * (a + 1) div + a * hessian, a in [-1,1]; a=1 */ cov_model *next = cov->sub[0]; cov_fct *N = CovList + next->nr; double norm[2], normSq0, normL2, normT2, D, D2, D3, diag, a = 1.0, // divergenz free b = - 0.5 * (1.0 + a); int i, td = cov->tsdim, dim = td, // ((int *)cov->p[1])[0], // currently no space-time allowed -> BA thesis dimP1 = dim + 1, dimP2 = dim + 2, dimP3 = dim + 3, dimP2sqM1 = dimP2 * dimP2 -1; // for three dimensions much // more complicated normL2 = normT2 = 0.0; for (i=0; iisoIn == ISOTROPIC) { normSq0 = normL2 + normT2; } else { normSq0 = normL2; norm[1] = sqrt(normT2); } norm[0] = sqrt(normSq0); N->D(norm, next, &D); N->D2(norm, next, &D2); N->D3(norm, next, &D3); if (normSq0 == 0.0) { for (i=0; i<=dimP2sqM1; i++) v[i] = 0.0; N->cov(norm, next, v); // v[0] diag = (b * dim + a) * D2; for (i=dimP3; iD2(norm, next, v + dimP1); v[dimP1] *= 2.0; v[dimP2 * dimP1] = v[dimP1]; N->D4(norm, next, v + dimP2sqM1); v[dimP2sqM1] *= (8.0 / 3.0); } else { double z[2], D2nsq = D2 / normSq0, D1n = D / norm[0], D3n = D3 / norm[0], D1n3 = D / (norm[0] * normSq0), delta = a * (D2nsq - D1n3), div = b * ((D2nsq - D1n3) * normL2 + dim * D1n); int k,l; N->cov(norm, next, v); // v[0] z[0] = -x[1]; z[1] = x[0]; for (i=1; i<=dim; i++) { // kante links und oben v[i] = -(v[i * dimP2] = z[i-1] * D1n); } diag = div + a * D1n; for (i= dimP3, k=0; kD4(norm, next, v + dimP2sqM1); // rechts unten v[dimP2sqM1] += 2.0 * D3n - D2nsq + D1n3; } // for (i=0; i<=15; i++) { // if (i!=15) v[i] = 0.0; // } } int checkdivcurl(cov_model *cov) { cov_model *next = cov->sub[0], *nexttrue=next->sub[0]; // next is gatter and derivatives have not // been programmed yet // cov_fct *N = CovList + next->sub[0]->nr; int err, dim = cov->tsdim, spacedim; isotropy_type isotropy; cov->normalmix = cov->finiterange = false; cov->manipulating_x=true; if ((err = check2X(next, dim, 1, STATIONARY, ISOTROPIC, UNIVARIATE)) != NOERROR) { if ((err = check2X(next, dim, 1, STATIONARY, SPACEISOTROPIC, UNIVARIATE)) != NOERROR) return err; } if (nexttrue->derivatives < 4) ERR("4th derivative of submodel not defined"); if (cov->tsdim != 2) ERR("currently coded only for dim=2"); isotropy = next->isoIn; spacedim = dim - (isotropy == SPACEISOTROPIC); if (isotropy != ISOTROPIC && isotropy != SPACEISOTROPIC) ERR("submodel must be spaceisotropic"); if (spacedim != 2) ERR("model currently only defined for the plane"); setbackward(cov, next); cov->vdim = spacedim + 2; // only correct for spacedim == 2!!! assert(spacedim == 2); next->tsdim = DEL_COV; return NOERROR; } void rangedivcurl(cov_model *cov, range_arraytype* ra){ } void lp(double *x, cov_model *cov, double *v){ cov_model *next = cov->sub[0]; double z, p = cov->p[0][0]; int d, dim = cov->tsdim; for (z=0.0, d=0; dnr].cov(&z, next, v); } int checklp(cov_model *cov) { bool skipchecks = GLOBAL.general.skipchecks; cov_fct *C = CovList + cov->nr; cov_model *next = cov->sub[0]; double p; int err; kdefault(cov, 0, 1.0); p =cov->p[0][0]; if ((err = checkkappas(cov)) != NOERROR) return err; cov->manipulating_x=true; strcpy(ERROR_LOC, C->name); if ((err = check2X(next, cov->tsdim + 1, 1, STATIONARY, ISOTROPIC, UNIVARIATE)) != NOERROR) return err; next->tsdim = DEL_COV; if (p==1) { cov->maxdim = next->maxdim - 1; // true for p==1 if (cov->maxdim == 0) cov->maxdim = 1; } else if (p==2) { cov->maxdim = next->maxdim; } else if (!skipchecks) ERR("p must be 1 or 2."); cov->normalmix = next->normalmix; cov->semiseparatelast = false; updatepref(cov, next); return NOERROR; } void rangelp(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges; range->min[0] = 0.0; range->max[0] = 2.0; range->pmin[0] = 0.01; range->pmax[0] = 2.0; range->openmin[0] = true; range->openmax[0] = false; } void ma1(double *x, cov_model *cov, double *v){ cov_model *next = cov->sub[0]; double z, alpha = cov->p[0][0], theta = cov->p[1][0]; CovList[next->nr].cov(x, next, &z); *v = pow(theta / (1 - (1-theta) * z), alpha); } int checkma1(cov_model *cov) { // bool skipchecks = GLOBAL.general.skipchecks; cov_fct *C = CovList + cov->nr; cov_model *next = cov->sub[0]; // double p; int err; kdefault(cov, 0, 1.0); kdefault(cov, 1, 0.5); if ((err = checkkappas(cov)) != NOERROR) return err; strcpy(ERROR_LOC, C->name); if ((err = check2X(next, cov->tsdim, cov->xdim, cov->statIn, cov->isoIn, UNIVARIATE)) != NOERROR) return err; cov->semiseparatelast = false; // updatepref(cov, next); return NOERROR; } void rangema1(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges; range->min[0] = 0.0; range->max[0] = RF_INF; range->pmin[0] = 0.01; range->pmax[0] = 10; range->openmin[0] = true; range->openmax[0] = true; range->min[1] = 0.0; range->max[1] = 1.0; range->pmin[1] = 0.0; range->pmax[1] = 1.0; range->openmin[1] = true; range->openmax[1] = true; } void ma2(double *x, cov_model *cov, double *v){ cov_model *next = cov->sub[0]; double z,z0; CovList[next->nr].cov(ZERO, next, &z0); CovList[next->nr].cov(x, next, &z); z = z0 - z; *v = (z == 0) ? 1.0 : (1.0 - exp(-z)) / z; } int checkma2(cov_model *cov) { // bool skipchecks = GLOBAL.general.skipchecks; cov_fct *C = CovList + cov->nr; cov_model *next = cov->sub[0]; // double p; int err; if ((err = checkkappas(cov)) != NOERROR) return err; cov->manipulating_x = true; strcpy(ERROR_LOC, C->name); if ((err = check2X(next, cov->tsdim, cov->xdim, VARIOGRAM, cov->isoIn, UNIVARIATE)) != NOERROR) return err; cov->semiseparatelast = false; // updatepref(cov, next); return NOERROR; } void rangema2(cov_model *cov, range_arraytype* ra){ } void kappaM(int i, cov_model *cov, int *nr, int *nc){ *nc = 0; *nr = i < 1 ? 0 : -1; } void M(cov_model *cov, double *Z, double *V) { // M^t C M cov_model *next = cov->sub[0]; int *ncol = cov->ncol, *nrow = cov->nrow; double *MtZ, alpha = 1.0, beta = 0.0, *M = cov->p[0]; // SUBROUTINE DGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC) // C := alpha*op( A )*op( B ) + beta*C, // M : rows of op(A) // N : cols of op(B) // K : cols of op(A)= rows of op(B) // LD-X : first dimension of X if (next->vdim == 1) { MtZ = (double*) malloc(sizeof(double) * *ncol * *ncol); F77_CALL(dgemm)("T", "N", ncol, ncol, nrow, Z, M, nrow, M, nrow, &beta, V, ncol); } else { MtZ = (double*) malloc(sizeof(double) * *nrow * *ncol); F77_CALL(dgemm)("T", "N", ncol, nrow, nrow, &alpha, M, nrow, Z, nrow, &beta, MtZ, ncol); F77_CALL(dgemm)("N", "N", ncol, ncol, nrow, &alpha, MtZ, ncol, M, nrow, &beta, V, ncol); } free(MtZ); } void Mstat(double *x, cov_model *cov, double *v){ cov_model *next = cov->sub[0]; int ncol = cov->ncol[0]; double *z = (double*) malloc(sizeof(double) * ncol * ncol); CovList[next->nr].cov(x, next, z); M(cov, z, v); free(z); } void Mnonstat(double *x, double *y, cov_model *cov, double *v){ cov_model *next = cov->sub[0]; int ncol = cov->ncol[0]; double *z = (double*) malloc(sizeof(double) * ncol * ncol); CovList[next->nr].nonstat_cov(x, y, next, z); M(cov, z, v); free(z); } int checkM(cov_model *cov) { cov_model *next = cov->sub[0]; int err; if ((err = check2X(next, cov->tsdim, cov->xdim, cov->statIn, cov->isoIn, cov->nrow[0])) != NOERROR) return err; setbackward(cov, next); cov->vdim = cov->ncol[0]; err = checkkappas(cov); return err; } void rangeM(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges; range->min[0] = RF_NEGINF; range->max[0] = RF_INF; range->pmin[0] = -1e10; range->pmax[0] = 1e10; range->openmin[0] = true; range->openmax[0] = true; range->finiterange = true; } void IdStat(double *x, cov_model *cov, double *v) { cov_model *next = cov->sub[0]; CovList[next->nr].cov(x, next, v); } void IdNonStat(double *x, double *y, cov_model *cov, double *v){ cov_model *next = cov->sub[0]; CovList[next->nr].nonstat_cov(x, y, next, v); } int checkId(cov_model *cov) { cov_model *next = cov->sub[0]; int err; cov->vdim = (cov->nrow[0] > 0 && cov->nrow[0] > 0) ? ((int*) cov->p[0])[0] : SUBMODELM; if ((err = check2X(next, cov->tsdim, cov->xdim, cov->statIn, cov->isoIn, cov->vdim )) != NOERROR) return err; if (cov->vdim == SUBMODELM) cov->vdim = next->vdim; setbackward(cov, next); return NOERROR; } void DId(double *x, cov_model *cov, double *v){ cov_model *next = cov->sub[0]; CovList[next->nr].D(x, next, v); } void DDId(double *x, cov_model *cov, double *v){ cov_model *next = cov->sub[0]; CovList[next->nr].D2(x, next, v); } void TBM2Id(double *x, cov_model *cov, double *v){ cov_model *next = cov->sub[0]; CovList[next->nr].tbm2(x, next, v); } int initspectralId(cov_model *cov) { cov_model *next = cov->sub[0]; return CovList[next->nr].initspectral(next); } void spectralId(cov_model *cov, spectral_storage *s, double *e) { cov_model *next = cov->sub[0]; return CovList[next->nr].spectral(next, s, e); } void coinitId(cov_model *cov, localinfotype *li) { cov_model *next = cov->sub[0]; CovList[next->nr].coinit(next, li); } void ieinitId(cov_model *cov, localinfotype *li) { cov_model *next = cov->sub[0]; CovList[next->nr].ieinit(next, li); } void rangeId(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges; range->min[0] = 1.0; range->max[0] = RF_INF; range->pmin[0] = 1.0; range->pmax[0] = 10; range->openmin[0] = false; range->openmax[0] = true; range->finiterange = true; range->maxdim = INFDIM; } void Exp(double *x, cov_model *cov, double *v){ double v0, v1; cov_model *next = cov->sub[0]; cov_fct *C = CovList + next->nr; C->cov(ZERO, next, &v0); C->cov(x, next, &v1); *v = exp(v1-v0); // == - (v0 - v1) } void DExp(double *x, cov_model *cov, double *v){ double D; cov_model *next = cov->sub[0]; cov_fct *C = CovList + next->nr; C->D(x, next, &D); Exp(x, cov, v); *v *= -D; } void DDExp(double *x, cov_model *cov, double *v){ double D, D2; cov_model *next = cov->sub[0]; cov_fct *C = CovList + next->nr; C->D(x, next, &D); C->D2(x, next, &D2); Exp(x, cov, v); *v *= D * D + D2; // Achtung + D2 nicht - D2, da D2 Ableitung einer Cov. } int checkExp(cov_model *cov) { cov_model *next = cov->sub[0]; int err; if (cov->statIn != STATIONARY && cov->statIn != VARIOGRAM) return ERRORSTATVARIO; if ((err = check2X(next, cov->tsdim, cov->xdim, cov->statIn, cov->isoIn, UNIVARIATE)) != NOERROR) return err; cov->manipulating_x=true; setbackward(cov, next); cov->normalmix = false; return NOERROR; } void rangeExp(cov_model *cov, range_arraytype* ra) { } void Pow(double *x, cov_model *cov, double *v){ double v0, v1, alpha = cov->p[0][0]; cov_model *next = cov->sub[0]; cov_fct *C = CovList + next->nr; C->cov(ZERO, next, &v0); C->cov(x, next, &v1); *v = v0 - pow(v0 - v1, alpha); // printf("Pow %f %f %f v=%f\n", v0, v1, alpha, *v); } void DPow(double *x, cov_model *cov, double *v){ double v0, v1, gamma, alpha = cov->p[0][0]; cov_model *next = cov->sub[0]; cov_fct *C = CovList + next->nr; C->D(x, next, v); if (alpha == 1.0) return; C->cov(ZERO, next, &v0); C->cov(x, next, &v1); gamma = v0 - v1; *v *= - alpha * pow(gamma, alpha -1.0); // Achtung "-" , da covarianzfunktion angenommen } void DDPow(double *x, cov_model *cov, double *v){ double D, v0, v1, gamma, alpha = cov->p[0][0]; cov_model *next = cov->sub[0]; cov_fct *C = CovList + next->nr; C->D2(x, next, v); if (alpha == 1.0) return; C->D(x, next, &D); C->cov(ZERO, next, &v0); C->cov(x, next, &v1); gamma = v0 - v1; *v *= - alpha * pow(gamma, alpha - 2.0) * ((alpha - 1.0) * D + gamma * (*v)); // Achtung "-" , da covarianzfunktion angenommen } void invPow(double *x, cov_model *cov, double *v) { // invPow only defined for submodel having variance 1 !!!! cov_model *next = cov->sub[0]; cov_fct *C = CovList + next->nr; C->cov(x, next, v); double y = 1.0 - *v; if (y < 0.0 || y > 1.0) { if (y > -1e-14 && y < 0.0) y=0.0; else if (y < 1.0 + 1e-14) y=1.0; else { //PRINTF("covariance value %e (1 - %e = %e) at %e\n", *v, *v, 1.0-*v, *x); ERR("invPow valid only for non-negative covariance models with variance 1"); } } *v = 1.0 - pow(y, 1.0 / cov->p[0][0]); // printf("%f %f %f\n", y, *v, cov->p[0][0]); // printf("Inv %f %f %f v=%f\n", *x, cov->p[0][0],y, *v); } int checkPow(cov_model *cov) { cov_model *next = cov->sub[0]; // cov_fct *C = CovList + next->nr; int err; //printf("OK %d %d\n", cov->statIn, cov->isoIn); cov->manipulating_x=true; if (cov->statIn != STATIONARY && cov->statIn != VARIOGRAM) return ERRORSTATVARIO; if ((err = check2X(next, cov->tsdim, cov->xdim, cov->statIn, cov->isoIn, UNIVARIATE)) != NOERROR){ // printf("OK %d\n",err); return err; } // printf("xOK %d\n",err); setbackward(cov, next); cov->normalmix = false; if (cov->statIn == STATIONARY && next->normalmix) { cov->normalmix = true; } return NOERROR; } void rangePow(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges; range->finiterange = true; range->maxdim = INFDIM; range->min[0] = 0.0; range->max[0] = 1.0; range->pmin[0] = 0.01; range->pmax[0] = 1.0; range->openmin[0] = true; range->openmax[0] = false; } void tbm3(double *x, cov_model *cov, double *v){ cov_model *next = cov->sub[0]; double v1; cov_fct *C = CovList + next->nr; C->cov(x, next, v); C->D(x, next, &v1); (*v) += *x * v1 / cov->p[0][0]; } int checktbm3(cov_model *cov) { cov_model *next = cov->sub[0]; assert(next != NULL); int err, newdim; kdefault(cov, 0, 1); newdim = (int) cov->p[0][0]; if (cov->tsdim > newdim) return ERRORWRONGDIM; /// ?????? if (cov->isoIn != ISOTROPIC && cov->isoIn != SPACEISOTROPIC) return ERRORANISO; if ((err = check2X(next, 2 + newdim, cov->xdim, STATIONARY, cov->isoIn, UNIVARIATE)) != NOERROR) return err; if (cov->isoIn != SPACEISOTROPIC || next->sub[0]->isoIn == SPACEISOTROPIC) next->tsdim = DEL_COV; cov->derivatives = next->derivatives - 1; if (cov->derivatives < 0) { PrintModelInfo(cov); // ok ERR("derivative for the submodel does not exist or is unknown"); } cov->manipulating_x=true; setbackward(cov, next); cov->pref[CircEmbed] = next->pref[CircEmbed] + 1; if (cov->pref[CircEmbed] > PREF_BEST) cov->pref[CircEmbed] = PREF_BEST; return NOERROR; } void rangetbm3(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges; range->finiterange = true; range->maxdim = INFDIM; range->min[0] = 1.0; range->max[0] = RF_INF; range->pmin[0] = 1.0; range->pmax[0] = 1000000.0; range->openmin[0] = false; range->openmax[0] = true; } void tbm2(double *x, cov_model *cov, double *v){ cov_model *next = cov->sub[0]; cov_fct *C = CovList + next->nr; if (C->tbm2 == NULL) ERR("tbm2 operator is unavailable for the specified submodel"); C->tbm2(x, next, v); } int checktbm2(cov_model *cov){ cov_model *next = cov->sub[0]; assert(next != NULL); bool layer = cov->xdim == 2; int err; cov->nr = TBM2NR; cov->manipulating_x=true; if (cov->tsdim > 2 + layer) return ERRORWRONGDIM; assert(cov->xdim == 1 + layer); if ((err = check2X(next, 2 + layer, cov->xdim, STATIONARY, cov->isoIn, UNIVARIATE)) != NOERROR) return err; setbackward(cov, next); if (next->pref[TBM2] <= 0) { return ERRORCURRENTLY; cov->nr ++; // numerical evaluation ... } return NOERROR; } void rangetbm2(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges; range->finiterange = false; range->maxdim = 1; } typedef struct TBM2_integr{ cov_model *cov; double *x; bool layer; } TBM2_integr; void TBM2NumIntegrFct(double *u, int n, void *ex) { int i; double z[2]; TBM2_integr *info; info = (TBM2_integr*) ex; cov_model *cov=info->cov; double *x = info->x; for (i=0; iranges; range->maxdim = 0; assert(false); } int checkundefined(cov_model *cov) { assert(false); return NA_INTEGER; // info->CEbad = true; } /* qam */ void kappaqam(int i, cov_model *cov, int *nr, int *nc){ *nc = 1; *nr = (i==0) ? cov->nsub-1 : -1; } void qam(double *x, cov_model *cov, double *v) { cov_model *next = cov->sub[0]; cov_fct *C = CovList + next->nr; int i, nsub = cov->nsub; double sum, s, w, *theta = cov->p[0]; sum = 0.0; for (i=1; isub[i]; CovList[sub->nr].cov(x, sub, &s); C->invSq(&s, next, &w); sum += theta[i - 1] * w; } sum = sqrt(sum); C->cov(&sum, next, v); } int checkqam(cov_model *cov) { cov_model *next = cov->sub[0], *sub; int i, err, nsub = cov->nsub, nsubM1 = nsub - 1; double v, sum; if ((err = checkkappas(cov)) != NOERROR) return err; sum = 0.0; for (i=0; ip[0][i]; } if (fabs(sum - 1.0) > 1e-14) ERR("theta must sum up to 1"); cov->manipulating_x=true; cov->normalmix = true; cov->finiterange = false; if ((err = check2X(next, 1, 1, STATIONARY, ISOTROPIC, UNIVARIATE)) != NOERROR) return err; if (!next->normalmix) ERR("phi is not completely monotone"); for (i=1; isub[i]; if ((err = check2X(sub, cov->tsdim, cov->tsdim, STATIONARY, ANISOTROPIC, UNIVARIATE)) != NOERROR) return err; CovList[sub->nr].cov(ZERO, sub, &v); if (v != 1.0) return ERRORUNITVAR; setbackward(cov, sub); } return NOERROR; } void rangeqam(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges; range->min[0] = 0.0; range->max[0] = 1.0; range->pmin[0] = 0.0; range->pmax[0] = 1.0; range->openmin[0] = false; range->openmax[0] = false; } /* mqam */ void kappamqam(int i, cov_model *cov, int *nr, int *nc) { int nsub = cov->nsub - 1; *nc = (i==0) ? 1 : nsub; *nr = (i <= 1) ? nsub : -1; // printf("kappa %d nsub=%d %d %d\n", i, nsub, *nc, *nr); } void mqam(double *x, cov_model *cov, double *v) { cov_model *next = cov->sub[0]; cov_fct *C = CovList + next->nr; int i, j, k, l, nsub = cov->nsub, nsubM1 = nsub - 1; double s0, theta = cov->p[0][0], EMtheta = 1.0 - theta, *rho = cov->p[1], s[MAXSUB]; for (i=1; isub[i]; CovList[sub->nr].cov(x, sub, &s0); C->invSq(&s0, next, s + i - 1); } for (j=0; jcov(&s0, next, v + k); v[l] = v[k] * rho[l]; if (k != l) v[k] *= rho[k]; assert (rho[l] == rho[k]) ; // printf("%d %d %d %d %f %f %e %e\n", i, j, k, l, // v[k], rho[l], v[l]-v[k], rho[k]-rho[l]); } } } int checkmqam(cov_model *cov) { // cov_model *next = cov->sub[0]; int err, nsub = cov->nsub, nsubM1 = nsub - 1; if ((err = checkqam(cov)) != NOERROR) return err; cov->vdim = nsubM1; cov->manipulating_x=true; return NOERROR; } void rangemqam(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges; double pmax = 2.0 / (double) (cov->nsub-1); range->min[0] = 0.0; range->max[0] = 1.0; range->pmin[0] = 0.0; range->pmax[0] = pmax; range->openmin[0] = false; range->openmax[0] = false; range->min[1] = RF_NEGINF; range->max[1] = RF_INF; range->pmin[1] = -10.0; range->pmax[1] = 10.0; range->openmin[1] = true; range->openmax[1] = true; } /////////////// NATSC void natsc(double *x, cov_model *cov, double *v){ cov_model *next = cov->sub[0]; double scale, y; if (next->nr >= GATTER && next->nr <= LASTGATTER) { /* diese Abfrage muss bleiben, da roher aufruf ohne voriges DeleteGatter aus stein_st_check heraus erfolgt. Wenn Gatter gar nicht eingefuehrt wuerde, kann natsc nicht ueber checkX2 das primitive aufrufen */ next = next->sub[0]; } assert(CovList[next->nr].naturalscale != NULL); scale = CovList[next->nr].naturalscale(next); y = *x / scale; // letzteres darf nur passieren wenn dim = 1!! CovList[next->nr].cov(&y, next, v); } void Dnatsc(double *x, cov_model *cov, double *v){ cov_model *next = cov->sub[0]; int i, vdimSq = cov->vdim * cov->vdim; double scale, y; if (next->nr >= GATTER && next->nr <= LASTGATTER) next = next->sub[0]; assert(CovList[next->nr].naturalscale != NULL); scale = CovList[next->nr].naturalscale(next); y = *x / scale; CovList[next->nr].D(&y, next, v); for (i=0; isub[0]; int i, vdimSq = cov->vdim * cov->vdim; double scale, y, ScSq; if (next->nr >= GATTER && next->nr <= LASTGATTER) next = next->sub[0]; assert(CovList[next->nr].naturalscale != NULL); scale = CovList[next->nr].naturalscale(next); y = *x / scale; ScSq = scale * scale; CovList[next->nr].D2(&y, next, v); for (i=0; isub[0]; int i, vdimSq = cov->vdim * cov->vdim; double scale = CovList[next->nr].naturalscale(next); CovList[next->nr].D(x, next, v); for (i=0; isub[0]->sub[0]; if ( CovList[next->nr].coinit == NULL) error("# cannot find coinit -- please inform author"); CovList[next->nr].coinit(next, li); } void ieinitnatsc(cov_model *cov, localinfotype *li) { cov_model *next = cov->sub[0]->sub[0]; if ( CovList[next->nr].ieinit == NULL) error("# cannot find ieinit -- please inform author"); CovList[next->nr].ieinit(next, li); } void tbm2natsc(double *x, cov_model *cov, double *v){ cov_model *next = cov->sub[0]; cov_fct *C = CovList + next->nr; double scale = CovList[next->nr].naturalscale(next), y = x[0] / scale; // purely spatial , C->tbm2(&y, next, v); } int checknatsc(cov_model *cov) { cov_model *next = cov->sub[0]; cov_fct *C = CovList + cov->nr; int err; strcpy(ERROR_LOC, C->name); assert(cov->nr == NATSC); cov->manipulating_x = true; if ((err = check2X(next, cov->tsdim, cov->xdim, cov->statIn, cov->isoIn, SUBMODELM)) != NOERROR) { return err; } if (next->sub[0]->statIn == cov->statIn && next->sub[0]->isoIn == cov->isoIn) { next->tsdim = DEL_COV - 12; } // PrintModelInfo(cov); // printf(" %d %d %d %d \n", next->sub[0]->statIn, cov->statIn, // next->sub[0]->isoIn, cov->isoIn); // assert(false); // now, next is shifted behind gatter !!: if (next->nr >= GATTER && next->nr <= LASTGATTER) { next = next->sub[0]; } else ERR("natsc: # expected -- contact author"); if (CovList[next->nr].naturalscale == NULL) { sprintf(ERRORSTRING, "natural scaling is not defined for %s", CovList[next->nr].name); return ERRORFAILED; } cov->vdim = next->vdim; setbackward(cov, next); return NOERROR; } int initspectralnatsc(cov_model *cov) { cov_model *next = cov->sub[0]; if (CovList[next->nr].initspectral == NULL) { // PRINTF("natsc: %ld %s\n", // (POINTER) CovList[next->nr].initspectral, CovList[next->nr].name); PrintModelInfo(cov); assert(CovList[next->nr].initspectral != NULL); } return CovList[next->nr].initspectral(next); } void spectralnatsc(cov_model *cov, spectral_storage *s, double *e) { cov_model *next = cov->sub[0]; int d, dim = cov->tsdim; double scale = CovList[next->nr].naturalscale(next); CovList[next->nr].spectral(next, s, e); for (d=0; dcov, *next = cov->sub[0]; // globalparam *gp = meth->gp; int err, i, origdim = meth->loc->timespacedim, total = origdim * meth->xdimout; double scale = CovList[next->nr].naturalscale(next); // setAniso(meth); // schon im S-Teil ist die neue c-aniso gesetzt -- // S-Teil darf somit nicht mit c-aniso aufgerufen werden // siehe doS, das sofort naechsten Teil aufruft. meth->sub[0] = (method_type*) malloc(sizeof(method_type)); METHOD_NULL(meth->sub[0]); meth->nsub = 1; method_type *sub = meth->sub[0]; cpyMethod(meth, sub, false); // cum_dollar(meth, meth->loc->timespacedim, cov, sub); : if (meth->caniso != NULL) { sub->caniso = (double *) malloc(total * sizeof(double)); for (i=0; icaniso[i] = meth->caniso[i] / scale; } else { sub->cscale = meth->cscale / scale; } sub->cov = cov->sub[0]; err = initstandard(sub); meth->compatible = sub->compatible; meth->domethod = doS; meth->S = NULL; meth->nr = DOLLAR; return err; } void donatsc(method_type *meth, res_type *res){ do_meth dometh = meth->sub[0]->domethod; dometh(meth->sub[0], res); } //////////////////////////////////////////////////////////////////// void X(double *x, cov_model *cov, double *v){ cov_model *sub, *next = cov->sub[0]; listoftype *list = (listoftype*) (cov->p[0]), *sublist; double var; int i, end=cov->vdim*cov->vdim; if (LIST_ELEMENT < 0 || LIST_ELEMENT >= cov->nrow[0]) ERR("illegal call of 'X' (it may be used only within fitvario)"); if (cov->nrow[0] == 0) { // no X given CovList[next->nr].cov(x, cov, v); return; } else { if (!(bool*) cov->q) ERR("model 'const' expected"); // i.e. CONST if (CovMatrixRow >= list->nrow[LIST_ELEMENT] || CovMatrixCol >= list->ncol[LIST_ELEMENT]) { ERR("matrices are not sufficently large"); } sub = next; var = 1.0; if (sub->nr >= GATTER && sub->nr <= LASTGATTER) sub=sub->sub[0]; if (sub->nr >= DOLLAR && sub->nr <= LASTDOLLAR) { var = sub->p[DVAR][0]; sub=sub->sub[0]; if (sub->nr >= GATTER && sub->nr <= LASTGATTER) sub=sub->sub[0]; } sublist = (listoftype*) (sub->p[0]); if (list->ncol[LIST_ELEMENT] != sublist->nrow[LIST_ELEMENT]) ERR("mixed model: X and covariance matrix M do not match"); *v = XkCXtl(list->p[LIST_ELEMENT], sublist->p[LIST_ELEMENT], list->nrow[LIST_ELEMENT], list->ncol[LIST_ELEMENT], CovMatrixRow, CovMatrixCol); for (i=0; insub != 0 && cov->nrow[0] == 0) { // no X given, but a submodel cov_model *next = cov->sub[0]; CovList[next->nr].nonstat_cov(x, y, next, v); return; } X(x, cov, v); } // ToDO : write simulation init, do !!! int checkX(cov_model *cov) { cov_model *sub, *next = cov->sub[0]; int err, *nrow = cov->nrow; // taken[MAX DIM], // *ncol = cov->ncol, // listoftype *list = (listoftype*) (cov->p[0]); bool *Const; CovMatrixRow = CovMatrixCol = INT_MAX; cov->vdim = 1; if (cov->nsub!=1) error("nsub must be 1"); if (cov->q == NULL) cov->q = (double*) malloc(sizeof(bool)); Const = ((bool*) cov->q); // PrintModelInfo(next); sub = next; if (sub->nr >= GATTER && sub->nr <= LASTGATTER) sub=sub->sub[0]; if (sub->nr >= DOLLAR && sub->nr <= LASTDOLLAR) { sub=sub->sub[0]; if (sub->nr >= GATTER && sub->nr <= LASTGATTER) sub=sub->sub[0]; } *Const = sub->nr == CONSTANT; // printf("call: %s %s\n", CovList[next->nr].name, CovList[next->sub[0]->nr].name); if ((err = check2X(next, cov->tsdim, cov->xdim, cov->statIn, cov->isoIn, SUBMODELM)) != NOERROR) { // printf("error\n"); return err; } if (*Const) { next->tsdim = DEL_COV - 6; if (next->nr >= DOLLAR && next->nr<=LASTDOLLAR) next->sub[0]->tsdim = DEL_COV - 6; // if (ncol[0]==0) // ERR("if the cov. model is `const' in trend, then X must be given"); } else { if (nrow[0]>0) ERR("if the cov. model is not `const' in trend, then X may not be given"); } cov->vdim=sub->vdim; setbackward(cov, next); if (cov->vdim > 1) error("multivariate version not programmed yet"); // incorrect. but save !! cov->semiseparatelast = false; // taken[xdim - 1] <= 1; cov->separatelast = false; // taken[xdim - 1] <= 1; ?? return NOERROR; } void rangeX(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges + 0; range->min[0] = RF_NEGINF; range->max[0] = RF_INF; range->pmin[0] = -1e10; range->pmax[0] = 1e10; range->openmin[0] = true; range->openmax[0] = true; range->finiterange = false; } void mixed(double *x, cov_model *cov, double *v){ ERR("do not use 'mixed' as a component for the error -- use model 'X' instead"); } void mixed_nonstat(double *x, double *y, cov_model *cov, double *v){ mixed(x, cov, v); } void MLEmixed(double *x, cov_model *cov, double *v){ cov_model *next = cov->sub[0]; int i, end = cov->vdim * cov->vdim; if (cov->nsub == 0) { for (i=0; inr].name); CovList[next->nr].cov(x, next, v); } } void MLEmixed_nonstat(double *x, double *y, cov_model *cov, double *v){ cov_model *next = cov->sub[0]; int i, end = cov->vdim * cov->vdim; if (cov->nsub == 0) { for (i=0; inr].nonstat_cov(x, y, next, v); } } int checkmixed(cov_model *cov) { // cov_model *sub; int i, err, nsub = cov->nsub, *ncol = cov->ncol, *nrow = cov->nrow; // taken[MAX DIM], char msg[50]; listoftype *list = (listoftype*) (cov->p[0]); CovMatrixRow = CovMatrixCol = INT_MAX; cov->vdim = 1; if (ncol[1] > 0) { // b is given if (ncol[0] == 0) ERR("if b is given X must be given"); if (nsub != 0) ERR("either b or a covariance model must be given in trend"); for (i=0; incol[i] != nrow[1]) { sprintf(msg, "%dth set: (%d x %d) matrix X and (%d x %d) vector b do not match", i, list->nrow[0], list->ncol[i], nrow[1], ncol[1]); ERR(msg); } } } else if (nsub == 0) { // only X is given -- then only a deterministic // constant is given if (ncol[1] == 0) ERR("if no covariance model is given in mixed model then b must be given"); if (ncol[0] != 1) // deterministic effect ERR("X must have one column"); } else { // submodel is given cov_model *sub, *next = cov->sub[0]; bool *Const; if (cov->q == NULL) cov->q = (double*) malloc(sizeof(bool)); Const = ((bool*) cov->q); // PrintModelInfo(next); sub = next; if (sub->nr >= GATTER && sub->nr <= LASTGATTER) sub=sub->sub[0]; if (sub->nr >= DOLLAR && sub->nr <= LASTDOLLAR) { sub=sub->sub[0]; if (sub->nr >= GATTER && sub->nr <= LASTGATTER) sub=sub->sub[0]; } *Const = sub->nr == CONSTANT; // printf("call: %s %s\n", CovList[next->nr].name, CovList[next->sub[0]->nr].name); if ((err = check2X(next, cov->tsdim, cov->xdim, cov->statIn, cov->isoIn, SUBMODELM)) != NOERROR) { // printf("error\n"); return err; } if (*Const) { next->tsdim = DEL_COV - 6; if (next->nr >= DOLLAR && next->nr<=LASTDOLLAR) next->sub[0]->tsdim = DEL_COV - 6; // if (ncol[0]==0) // ERR("if the cov. model is `const' in trend, then X must be given"); } else { if (nrow[0]>0) ERR("if the cov. model is not `const' in trend, then X may not be given"); } cov->vdim=sub->vdim; setbackward(cov, next); } if (cov->vdim > 1) error("multivariate version not programmed yet"); // incorrect. but save !! cov->semiseparatelast = false; // taken[xdim - 1] <= 1; cov->separatelast = false; // taken[xdim - 1] <= 1; ?? return NOERROR; } void rangemixed(cov_model *cov, range_arraytype* ra){ range_type *range = ra->ranges + 0; int i; for (i=0; i<=1; i++) { range->min[i] = RF_NEGINF; range->max[i] = RF_INF; range->pmin[i] = -1e10; range->pmax[i] = 1e10; range->openmin[i] = true; range->openmax[i] = true; } range->finiterange = false; } typedef struct mixed_storage { // bool genuine_dim[MAX362DIM]; key_type key; double *b; } mixed_storage; void mixed_destruct(void ** S) { if (*S!=NULL) { mixed_storage *s = *((mixed_storage**) S); if (s->b != NULL) free(s->b); free(*S); *S = NULL; } } void mixed_NULL(mixed_storage* s) { KEY_NULL(&(s->key)); s->b = NULL; } int initmixed(method_type *meth) { return ERRORNOTPROGRAMMED; /* location_type *loc = meth->loc; mixed_storage *s; globalparam *gp = meth->gp; cov_model *cov= meth->cov, *next = cov->sub[0]; char errorloc_save[nErrorLoc]; int err; // cholesky zerlegung + bereitstellung von b SET_DESTRUCT(mixed_destruct); meth->domethod = dotrend; meth->compatible = true; if (next==NULL) return NOERROR; // submodel exists: if ((meth->S = malloc(sizeof(mixed_storage)))==0){ err=ERRORMEMORYALLOCATION; goto ErrorHandling; } s = (mixed_storage*) meth->S; mixed_NULL(s); if ((s->b = malloc(sizeof(double) * loc->totalpoints)) == 0) { err=ERRORMEMORYALLOCATION; goto ErrorHandling; } strcpy(errorloc_save, ERROR_LOC); sprintf(ERROR_LOC, "%s%s: ", errorloc_save, METHODNAMES[method]); err = internal_InitSimulateRF(loc->x, loc->T, loc->spatialdim, loc->lx, loc->grid, loc->Time, meth->simu.distribution, &(s->key), &global, 1, next); strcpy(ERROR_LOC, errorloc_save); if (err == NOERROR) return; ErrorHandling: return err; */ } void domixed(method_type *meth, res_type *res){ error("domixed not programmed yet"); /* int i; cov_model *cov = meth->cov, *next = cov->sub[0]; double *b; */ }