/* Authors Marco Oesting, Martin Schlather, schlather@math.uni-mannheim.de simulation of Brown-Resnick processes Copyright (C) 2009 -- 2010 Martin Schlather Copyright (C) 2011 -- 2015 Marco Oesting & 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 PURSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include "RF.h" #include "Operator.h" #define BR_MESHSIZE (LAST_MAXSTABLE + 1) #define BR_VERTNUMBER (LAST_MAXSTABLE + 2) #define BR_OPTIM (LAST_MAXSTABLE + 3) #define BR_OPTIMTOL (LAST_MAXSTABLE + 4) #define BR_OPTIMMAX (LAST_MAXSTABLE + 5) #define BR_LAMBDA (LAST_MAXSTABLE + 6) #define BR_OPTIMAREA (LAST_MAXSTABLE + 7) #define BR_VARIOBOUND (LAST_MAXSTABLE + 8) // ********************************************************************** // Brown Resnick int checkBrownResnickProc(cov_model *cov) { NotProgrammedYet("at the moment Brown-Resnick processes"); cov_model *key = cov->key, *sub = key != NULL ? key : cov->sub[cov->sub[MPP_SHAPE] != NULL ? MPP_SHAPE: MPP_TCF]; int err, role, dim = cov->tsdim; isotropy_type isoprev; Types type; ASSERT_CARTESIAN; ASSERT_ONE_SUBMODEL(cov); if ((err = SetGEVetc(cov, ROLE_BROWNRESNICK)) != NOERROR) return err; role = isVariogram(sub) ? ROLE_COV : (isGaussProcess(sub) && isPointShape(cov)) ? ROLE_GAUSS : isBrownResnickProcess(sub) ? ROLE_BROWNRESNICK : isPointShape(sub) ? ROLE_BROWNRESNICK : ROLE_UNDEFINED; type = isProcess(sub) || isPointShape(sub) ? CovList[sub->nr].Typi[0] : VariogramType; ASSERT_ROLE_DEFINED(sub); isoprev = role == ROLE_COV ? SYMMETRIC : CARTESIAN_COORD; if ((err = CHECK(sub, dim, dim, type,//Martin: changed 27.11.13 CovList[cov->nr].Type, XONLY, isoprev, 1, role)) != NOERROR) { return err; } setbackward(cov, sub); if (cov->vdim[0] != 1) SERR("BR only works in the univariate case"); return NOERROR; } #define ORIG_IDX 0 int init_BRorig(cov_model *cov, gen_storage *s){ cov_model *key = cov->key; location_type *keyloc = NULL; int err, d, dim = cov->tsdim; bool keygrid; br_storage *sBR = NULL; if (cov->role != ROLE_BROWNRESNICK) ILLEGAL_ROLE; if (key == NULL) BUG; if ((err = alloc_cov(cov, dim, 1, 1)) != NOERROR) return err; pgs_storage *pgs = cov->Spgs; for (d=0; dsupportmin[d] = RF_NEGINF; // 4 * for debugging... pgs->supportmax[d] = RF_INF; pgs->supportcentre[d] = RF_NA; } pgs->log_density = 0.0; keyloc = Loc(key); keygrid = keyloc->grid; key->simu.active = true; key->simu.expected_number_simu = cov->simu.expected_number_simu; assert(cov->mpp.moments >= 1); if ((err = INIT(key, 1, s)) != NOERROR) goto ErrorHandling; cov->loggiven = true; assert(key->nr == GAUSSPROC); assert(key->mpp.moments >= 1); cov->mpp.mM[0] = cov->mpp.mMplus[0] = 1.0; cov->mpp.mM[1] = cov->mpp.mMplus[1] = 1.0; cov->mpp.maxheights[0] = exp(GLOBAL.extreme.standardmax); pgs->zhou_c = 1.0; sBR = cov->Sbr; sBR->trendlen = 1; if ((sBR->trend = (double**) MALLOC(sizeof(double*)))==NULL) { err = ERRORMEMORYALLOCATION; goto ErrorHandling; } if ((sBR->trend[ORIG_IDX] = (double*) MALLOC(keyloc->totalpoints*sizeof(double)) ) == NULL) { err = ERRORMEMORYALLOCATION; goto ErrorHandling; } if ((err = loc_set(keygrid ? keyloc->xgr[0] : keyloc->x, NULL, NULL, dim, dim, keygrid ? 3 : keyloc->totalpoints, 0, false, keygrid, keyloc->distances, cov->Sbr->vario)) > NOERROR) goto ErrorHandling; if (sBR->vario->sub[0] != NULL) SetLoc2NewLoc(sBR->vario->sub[0], PLoc(sBR->vario)); Variogram(NULL, sBR->vario, sBR->trend[ORIG_IDX]); if ((err = FieldReturn(cov)) != NOERROR) // must be later than INIT ! goto ErrorHandling; ErrorHandling: if (err != NOERROR) br_DELETE(&(cov->Sbr)); return err; } void do_BRorig(cov_model *cov, gen_storage *s) { cov_model *key = cov->key; assert(key != NULL); br_storage *sBR = cov->Sbr; assert(sBR != NULL && sBR->trend != NULL); double *res = cov->rf; #define ORIG_IDX 0 int i, zeropos = sBR->zeropos[ORIG_IDX]; long totalpoints = Loc(cov)->totalpoints; assert(totalpoints > 0); assert(zeropos >= 0 && zeropos trend[ORIG_IDX]; assert(cov->origrf); DO(key, s); // nicht gatternr, double *lgres = key->rf; double lgreszeropos = (double) lgres[zeropos]; // wird durch DO veraendert! for (i=0; ikey; location_type *keyloc = NULL; int d, dim, err = NOERROR; long j, shiftedloclen, keytotal, trendlenmax, trendlenneeded; bool keygrid; br_storage *sBR = NULL; if (cov->role == ROLE_BROWNRESNICK) { if (key != NULL) { dim = cov->tsdim; if ((err = alloc_cov(cov, dim, 1, 1)) != NOERROR) return err; pgs_storage *pgs = cov->Spgs; for (d=0; dsupportmin[d] = RF_NEGINF; // 4 * for debugging; pgs->supportmax[d] = RF_INF; pgs->supportcentre[d] = RF_NA; } pgs->log_density = 0.0; keyloc = Loc(key); keygrid = keyloc->grid; keytotal = keyloc->totalpoints; key->simu.active = true; key->simu.expected_number_simu = cov->simu.expected_number_simu; assert(cov->mpp.moments >= 1); if ((err = INIT(key, 1, s)) != NOERROR) return err; cov->loggiven = true; assert(key->nr == GAUSSPROC); assert(key->mpp.moments >= 1); cov->mpp.mM[0] = cov->mpp.mMplus[0] = 1.0; cov->mpp.mM[1] = cov->mpp.mMplus[1] = 1.0; cov->mpp.maxheights[0] = exp(GLOBAL.extreme.standardmax); pgs->zhou_c = 1.0; sBR = cov->Sbr; shiftedloclen = keygrid ? 3 : keytotal; if ((sBR->shiftedloc = (double*) MALLOC(dim*shiftedloclen*sizeof(double))) == NULL || (sBR->locindex = (int*) MALLOC(sizeof(int) * dim))==NULL ) { err=ERRORMEMORYALLOCATION; goto ErrorHandling; } trendlenmax = (int) ceil((double) GLOBAL.br.BRmaxmem / keytotal); trendlenneeded = MIN(keytotal, cov->simu.expected_number_simu); sBR->trendlen = MIN(trendlenmax, trendlenneeded); assert(sBR->trendlen > 0); sBR->memcounter = 0; if ((sBR->loc2mem=(int*) MALLOC(sizeof(int)*keytotal))==NULL) { err = ERRORMEMORYALLOCATION; goto ErrorHandling; } for (j=0; jloc2mem[j] = -1; if ((sBR->mem2loc=(int*) MALLOC(sizeof(int)*sBR->trendlen))==NULL) { err = ERRORMEMORYALLOCATION; goto ErrorHandling; } if ((sBR->trend=(double**) MALLOC(sizeof(double*)*sBR->trendlen)) ==NULL) { err = ERRORMEMORYALLOCATION; goto ErrorHandling; } for (j=0; jtrendlen; j++) { sBR->mem2loc[j] = -1; if ((sBR->trend[j] = (double*) MALLOC(keytotal*sizeof(double)))==NULL) { err = ERRORMEMORYALLOCATION; goto ErrorHandling; } } if ((err = loc_set(keygrid ? keyloc->xgr[0] : keyloc->x, NULL, NULL, dim, dim, keygrid ? 3 : keytotal, 0, false, keygrid, keyloc->distances, sBR->vario)) > NOERROR) return err; if (sBR->vario->sub[0] != NULL) SetLoc2NewLoc(sBR->vario->sub[0], PLoc(sBR->vario)); if ((err = FieldReturn(cov)) != NOERROR) // must be later than INIT ! return err; } goto ErrorHandling; // no error } else ILLEGAL_ROLE; ErrorHandling: if (err != NOERROR) br_DELETE(&(cov->Sbr)); return err; } void indextrafo(long onedimindex, double ** xgr, int dim, int *multidimindex) { int d; for (d=0; dSbr; cov_model *key = cov->key; assert(cov->key != NULL); location_type *keyloc = Loc(key); long i, k, zeropos, zeroposMdim, keytotal = keyloc->totalpoints; int d, trendindex, dim = cov->tsdim, trendlen = sBR->trendlen, *locindex = sBR->locindex, *mem2loc = sBR->mem2loc, *loc2mem = sBR->loc2mem; bool keygrid = keyloc->grid; double *shiftedloc = sBR->shiftedloc, **xgr = keyloc->xgr, **trend = sBR->trend; assert(cov->origrf); double *res = cov->rf; double *lgres = cov->key->rf; DO(key, s); zeropos = (long) floor(UNIFORM_RANDOM * keytotal); if (loc2mem[zeropos] > -1) { trendindex = loc2mem[zeropos]; if (mem2loc[trendindex] != zeropos) BUG; } else { if (sBR->memcountermemcounter; sBR->memcounter++; } else { trendindex = trendlen - 1; loc2mem[mem2loc[trendlen-1]] = -1; mem2loc[trendlen-1] = -1; } if (keygrid) { indextrafo(zeropos, keyloc->xgr, dim, locindex); // to do: ersetzen for (d=0; dx[k] - keyloc->x[zeroposMdim+d]; } } } partial_loc_set(Loc(sBR->vario), shiftedloc, NULL, keygrid ? 3: keytotal, 0, keyloc->distances, dim, NULL, keygrid, true); if (sBR->vario->sub[0] != NULL) SetLoc2NewLoc(sBR->vario->sub[0], PLoc(sBR->vario)); Variogram(NULL, sBR->vario, sBR->trend[trendindex]); mem2loc[trendindex] = zeropos; // todo ? long instead of int loc2mem[zeropos] = trendindex; } for (i=0; ilogspeed) SERR("BrownResnick requires a variogram model as submodel that tends to infinity [t rate of at least 4log(h) for being compatible with BRmixed"); kdefault(cov, BR_MESHSIZE, bp->BRmeshsize); kdefault(cov, BR_VERTNUMBER, bp->BRvertnumber); kdefault(cov, BR_OPTIM, bp->BRoptim); kdefault(cov, BR_OPTIMTOL, bp->BRoptimtol); kdefault(cov, BR_OPTIMMAX, bp->BRoptimmaxpoints); kdefault(cov, BR_VARIOBOUND, bp->variobound); if (cov->nr == BRMIXED_USER && cov->key == NULL && P0INT(BR_OPTIM) > 0) { if (!PisNULL(BR_LAMBDA)) { if (PisNULL(BR_OPTIMAREA)) SERR1("'%s' not given", KNAME(BR_OPTIMAREA)); if (PL > 0) PRINTF("'%s' set to '0'", KNAME(BR_OPTIM)); PINT(BR_OPTIM)[0] = 0; } else if (P0INT(BR_OPTIM) == 2 && !PisNULL(BR_OPTIMAREA)) if (PL > 0) PRINTF("'%s' set to '1'", KNAME(BR_OPTIM)); } kdefault(cov, BR_LAMBDA, RF_NA); if (PisNULL(BR_OPTIMAREA)) //necessary as areamat might not be scalar kdefault(cov, BR_OPTIMAREA, 1.0); if ((err = checkBrownResnickProc(cov)) != NOERROR) return err; if ((err = checkkappas(cov, true)) != NOERROR) return err; if (cov->tsdim != cov->xdimprev || cov->tsdim != cov->xdimown) return ERRORDIM; if (cov->vdim[0] != 1) SERR("BR only works in the univariate case"); return NOERROR; } void kappaBRmixed(int i, cov_model *cov, int *nr, int *nc){ // i nummer des parameters int dim = cov->tsdim; switch(i) { case GEV_XI: case GEV_MU: case GEV_S: case BR_MESHSIZE: case BR_VERTNUMBER: case BR_OPTIM: case BR_OPTIMTOL: case BR_OPTIMMAX: case BR_LAMBDA: case BR_VARIOBOUND: *nr = 1; *nc = 1; break; case BR_OPTIMAREA: switch(dim) { case 1: *nr = 1; *nc = SIZE_NOT_DETERMINED; break; case 2: *nr = SIZE_NOT_DETERMINED; *nc = SIZE_NOT_DETERMINED; break; default: *nr = 1; *nc = 1; } break; default: *nr = -1; *nc = -1; } } void OptimArea(cov_model *cov, int idx) { // side effect auf P(BR_OPTIMAREA) !! br_storage *sBR = cov->Sbr; cov_model *key = sBR->sub[idx]; location_type *keyloc = Loc(key); double **xgr = keyloc->xgr; int d, i, j, k, l, zeroxpos, zeroypos, cellcounter, radius = (int) floor(xgr[0][XLENGTH] / 2.0), // ????? 1D ?? vertnumber = P0INT(BR_VERTNUMBER), radiusP1 = radius+1, dim = cov->tsdim, optimmax = P0INT(BR_OPTIMMAX) ; double dummy, Error, maxErrorbound, Errorbound, Errorboundtmp, Errortol = P0(BR_OPTIMTOL), step = P0(BR_MESHSIZE), stepdim= intpow(step, dim), **am = sBR->areamatrix ; // MARCO: ok?? // zwingend eine Kopie erstellen, da Vertauschen durchgefuehrt werden for (j=0; jcountvector[j]; for (d=0; d Error matrix for (j=0; j Errorbound) { Errorboundtmp = fmin(Errorboundtmp, am[j][d]); } } } Error = 0.0; cellcounter = 0; for (d=0; dnrow[BR_OPTIMAREA]; i++) { for (k=0; kncol[BR_OPTIMAREA]; k++, l++) { d = abs(k-zeroxpos) + abs(i-zeroypos); // abs OK optimarea[l] = 0.0; for (j=0; jSbr; int idx = 0; // first is the largest cov_model *key = sBR->sub[idx]; location_type *keyloc = Loc(key); double **xgr = keyloc->xgr; int i, j, d, sum_directions, radius = (int) floor(xgr[0][XLENGTH] * 0.5), // ?? radiusP1 = radius+1, vertnumber = P0INT(BR_VERTNUMBER), dim = cov->tsdim; switch(P0INT(BR_OPTIM)) { case 0: if (ISNAN(P0(BR_LAMBDA))) P(BR_LAMBDA)[0] = 1.0; break; case 1: // nothing to do break; case 2: if (dim > 2) BUG; sBR->vertnumber = vertnumber; sum_directions = 0; for (d=0; dcountvector != NULL || sBR->areamatrix != NULL) BUG; if ((sBR->countvector = (int**) CALLOC(vertnumber, sizeof(int*))) == NULL || (sBR->areamatrix = (double**) CALLOC(vertnumber, sizeof(double*))) == NULL|| (sBR->logvertnumber = (double *) MALLOC(vertnumber * sizeof(double))) ==NULL ) return ERRORMEMORYALLOCATION; for (i=0; i< vertnumber; i++) { if ((sBR->countvector[i] = (int*) CALLOC(sum_directions, sizeof(int))) == NULL || (sBR->areamatrix[i] = (double*) CALLOC(radiusP1, sizeof(double))) == NULL) return ERRORMEMORYALLOCATION; } for (j=0; jlogvertnumber[j] = - log((double) (j+1)/vertnumber); break; default: SERR("optimization might not be used here\n"); } if (PL >= PL_STRUCTURE) PRINTF("BR optimisation finished...\n"); return NOERROR; } void set_lowerbounds(cov_model *cov) { br_storage *sBR = cov->Sbr; assert(sBR != NULL); assert(sBR->sub[0] != NULL); double *optimarea = P(BR_OPTIMAREA); int i, l, ii, xbound = (int) floor(cov->ncol[BR_OPTIMAREA] * 0.5), ybound = (int) floor(cov->nrow[BR_OPTIMAREA] * 0.5); for (i=0; i<=sBR->maxidx; i++) { cov_model *key = sBR->sub[i]; location_type *keyloc = Loc(key); double **xgr = keyloc->xgr; long j, k, keytotal = keyloc->totalpoints, len = xgr[0][XLENGTH]; for (j=0; jlowerbounds[i][j] = RF_INF; for (l=0, ii=-ybound; ii<=ybound; ii++) { k = sBR->zeropos[i] + ii * len - xbound; for (j=-xbound; j<=xbound; j++, l++, k++) { if (optimarea[l]>1e-5) { sBR->lowerbounds[i][k] = -log(optimarea[l]); } } } } } int init_BRmixed(cov_model *cov, gen_storage *s) { location_type *loc = Loc(cov); int i, d, err = NOERROR, dim = cov->tsdim, bytes = sizeof(double) * dim; br_storage *sBR = cov->Sbr; assert(sBR != NULL); assert(sBR->sub[0] != NULL); pgs_storage *pgs = NULL; assert(isPointShape(cov)); if (cov->role != ROLE_BROWNRESNICK) ILLEGAL_ROLE; assert(dim > 0); sBR->idx = -1; sBR->trendlen = sBR->maxidx + 1; if ((err = alloc_cov(cov, dim, 1, 1)) != NOERROR) goto ErrorHandling;; // nur pgs pgs = cov->Spgs; // nach alloc_cov !! if ((sBR->suppmin = (double*) MALLOC(bytes))==NULL || (sBR->suppmax = (double*) MALLOC(bytes))==NULL || (sBR->locmin = (double*) MALLOC(bytes))==NULL || (sBR->locmax = (double*) MALLOC(bytes))==NULL || (sBR->loccentre = (double*) MALLOC(bytes))==NULL || (sBR->locindex = (int*) MALLOC(sizeof(int) * dim))==NULL || (sBR->trend == NULL && (sBR->trend = (double**) CALLOC(sBR->trendlen, sizeof(double*)))==NULL) ) { err = ERRORMEMORYALLOCATION; goto ErrorHandling; } GetDiameter(loc, sBR->locmin, sBR->locmax, sBR->loccentre); assert(pgs->supportmin != NULL); for (d=0; dsupportmin[d] = RF_NEGINF; pgs->supportmax[d] = RF_INF; } for (d=0; d<=cov->mpp.moments; d++) { cov->mpp.mM[d] = cov->mpp.mMplus[d] = 1.0; } if ((err = prepareBRoptim(cov, s)) != NOERROR) { goto ErrorHandling; } for (i=0; i<=sBR->maxidx; i++) { cov_model *key = sBR->sub[i]; location_type *keyloc = Loc(key); int keytotal = keyloc->totalpoints; assert(keyloc->grid); assert(key->nr == GAUSSPROC); key->simu.expected_number_simu = cov->simu.expected_number_simu; assert(cov->mpp.moments >= 1); if ((err = INIT(key, 1, s)) != NOERROR) goto ErrorHandling; key->simu.active = true; cov->loggiven = true; assert(key->mpp.moments >= 1); cov->mpp.mM[0] = cov->mpp.mMplus[0] = 1.0; cov->mpp.mM[1] = cov->mpp.mMplus[1] = 1.0; if (sBR->trend[i] == NULL && (sBR->trend[i] =(double*) MALLOC(keytotal*sizeof(double)))==NULL){ err = ERRORMEMORYALLOCATION; goto ErrorHandling; } if ((err = loc_set(keyloc->xgr[0], NULL, NULL, dim, dim, 3, 0, false, true, keyloc->distances, sBR->vario)) > NOERROR) goto ErrorHandling; if (sBR->vario->sub[0] != NULL) SetLoc2NewLoc(sBR->vario->sub[0], PLoc(sBR->vario)); Variogram(NULL, sBR->vario, sBR->trend[i]); if ((sBR->lowerbounds[i] = (double*) MALLOC(keytotal*sizeof(double))) == NULL) { err=ERRORMEMORYALLOCATION; goto ErrorHandling; } assert(keyloc != NULL); key->simu.active = true; } // for i<=maxid2 set_lowerbounds(cov); cov->rf = sBR->sub[0]->rf; cov->origrf = false; cov->fieldreturn = HUETCHEN_OWN_GRIDSIZE; pgs->estimated_zhou_c = ISNAN(P0(BR_LAMBDA)); pgs->zhou_c = pgs->estimated_zhou_c ? 0.0 : P0(BR_LAMBDA); pgs->logmean = true; pgs->sq_zhou_c = pgs->sum_zhou_c = 0.0; pgs->n_zhou_c = 0; sBR->next_am_check = GLOBAL.br.deltaAM; ErrorHandling: if (err != NOERROR) br_DELETE(&(cov->Sbr)); return err; } int IdxDistance(int maxind, int zeropos, double **xgr, int dim) { int d, delta = 0, x = maxind, y = zeropos; for (d=0; dkey!=NULL); br_storage *sBR = cov->Sbr; int d, dim = cov->tsdim; pgs_storage *pgs = cov->Spgs; assert(pgs != NULL); bool changedIdx; double area = 1.0, step = P0(BR_MESHSIZE), invstepdim = intpow(step, -dim); if ((changedIdx = pgs->currentthreshold == RF_NEGINF && sBR->idx != 0)) { sBR->idx = 0; // um zu gewaehrleisten, // dass insbesondere bei mehreren Simulationen wieder von vorne angefangen // wird } else if ((changedIdx = sBR->idx < sBR->maxidx && //pgs->currentthreshold < 0 ! pgs->currentthreshold >= sBR->thresholds[sBR->idx + 1])) { (sBR->idx)++; } assert(sBR->idx <= sBR->maxidx && sBR->maxidx < MAXSUB); cov_model *key = sBR->sub[sBR->idx]; // ! location_type *keyloc = Loc(key); double *lowerbounds = sBR->lowerbounds[sBR->idx], **xgr = keyloc->xgr, delta = sBR->radii[sBR->idx] + step; if (changedIdx) { if (PL > 5) PRINTF("current level in BRmixed is %d", sBR->idx); cov_model *prev = cov; while (prev->fieldreturn && !prev->origrf) { prev->rf = key->rf; prev = prev->calling; if (prev == NULL) break; } int *cumsum = pgs->own_grid_cumsum; cumsum[0] = 1; for (d=0; down_grid_len[d] = xgr[d][XLENGTH]; pgs->own_grid_step[d] = keyloc->xgr[d][XSTEP]; cumsum[d + 1] = cumsum[d] * pgs->own_grid_len[d]; } for (d=0; dsuppmin[d] = sBR->locmin[d] - delta; sBR->suppmax[d] = sBR->locmax[d] + delta; area *= sBR->suppmax[d] - sBR->suppmin[d]; } pgs->log_density = - log(area); cov->mpp.maxheights[0] = area; assert(cov->vdim[0] == 1 && cov->vdim[1] == 1); // MARCO lambda verstehe ich nicht -- wo/wie taucht lambda // in den einzelnen Huetchen auf? // @MARTIN: s. Zeile 957 } if (PL > 5) PRINTF("idx=%d %d %d zhou_n=%ld %d %d\n", sBR->idx, changedIdx, P0INT(BR_OPTIM), pgs->n_zhou_c, sBR->next_am_check, GLOBAL.br.deltaAM); if (P0INT(BR_OPTIM) == 2 && pgs->n_zhou_c >= sBR->next_am_check) { sBR->next_am_check += GLOBAL.br.deltaAM; OptimArea(cov, sBR->idx); set_lowerbounds(cov); } double *lgres = key->rf; // == cov->rf assert(cov->rf == key->rf); assert(keyloc->grid); int i, j, maxind, hatnumber, lgtotalpoints = keyloc->totalpoints, zeropos = sBR->zeropos[sBR->idx], vertnumber = P0INT(BR_VERTNUMBER); double maxval, u[MAXMPPDIM], *trend = sBR->trend[sBR->idx], radius = sBR->radii[sBR->idx]; for (d=0; dsuppmin[d] + UNIFORM_RANDOM*(sBR->suppmax[d] - sBR->suppmin[d]); pgs->supportmin[d] = u[d] - radius; pgs->supportmax[d] = u[d] + radius; pgs->own_grid_start[d] = keyloc->xgr[d][XSTART] + u[d]; } hatnumber=0; while(true) { DO(key, s); maxval = RF_NEGINF; maxind = 0; for (i=0; i maxval) { maxval = lgres[i]; maxind = i; } } if (maxind == zeropos) { pgs->sq_zhou_c += invstepdim * invstepdim; pgs->sum_zhou_c += invstepdim; } if (P0INT(BR_OPTIM) == 2) { int idxdist; double uplusmaxval = maxval - lgres[zeropos] - log(UNIFORM_RANDOM); for (j=0; j sBR->logvertnumber[j]) { // MARCO: ok? Warum wird die Schleife nach 1x abgebrochen? // ('first' braucht es somit eigentlich nicht. idxdist = IdxDistance(maxind, zeropos, xgr, dim); (sBR->countvector[j][idxdist])++; if (false && PL > 5) { int dd; for (dd=0; dd<75; dd++) { int value = sBR->countvector[j][dd]; if (value < 0) BUG; // memory zugriffs-fehler ueber valgrind sichtbar if (value<=9) PRINTF("%d", value); else if (value<=50) { PRINTF(value<=20 ? "A" : value<=30 ? "B" : value<=40 ? "C" : "D" ); } else PRINTF("#"); } PRINTF("j=%d\n", j); } break; } // else assert(maxval <= lowerbounds[maxind]); // nicht korrekt. } } else { assert(UNIFORM_RANDOM > -1.0); // nur umvergleichbarkeit von optim 1 und // optim 2 herzustellen } if (maxind == zeropos && PL > 5 && false) { PRINTF("zeropos maxval=%f lower=%f hat=%d zhou_n=%ld optim=%d\n", maxval, lowerbounds[maxind], hatnumber, pgs->n_zhou_c, P0INT(BR_OPTIM)); } // MARCO, dann es sein, dass die folgende Bedingung erfuellt ist, // aber uplusmaxval > sBR->logvertnumber[j] nicht erfuellt ist? if (maxval > lowerbounds[maxind]) break; hatnumber++; } pgs->n_zhou_c += hatnumber; if (PL >= PL_STRUCTURE && hatnumber > 300) PRINTF("note: large hat number (%d) might indicate numerically suboptimal framework\n", hatnumber); //shifting maximum to origin is not necessary because of stationarity //(conditional on T=t, the "correct" shape function is shifted which yields //the same stationary max-stable process; OK because there is a finite number //of values for t! for (i=0; imin[BR_MESHSIZE] = 0; range->max[BR_MESHSIZE] = RF_INF; range->pmin[BR_MESHSIZE] = 0; range->pmax[BR_MESHSIZE] = RF_INF; range->openmin[BR_MESHSIZE] = true; range->openmax[BR_MESHSIZE] = true; range->min[BR_VERTNUMBER] = 1; range->max[BR_VERTNUMBER] = RF_INF; range->pmin[BR_VERTNUMBER] = 1; range->pmax[BR_VERTNUMBER] = 50; range->openmin[BR_VERTNUMBER] = false; range->openmax[BR_VERTNUMBER] = false; range->min[BR_OPTIM] = 0; range->max[BR_OPTIM] = 2; range->pmin[BR_OPTIM] = 0; range->pmax[BR_OPTIM] = 2; range->openmin[BR_OPTIM] = false; range->openmax[BR_OPTIM] = false; range->min[BR_OPTIMTOL] = 0; range->max[BR_OPTIMTOL] = 1; range->pmin[BR_OPTIMTOL] = 0; range->pmax[BR_OPTIMTOL] = 0.1; range->openmin[BR_OPTIMTOL] = true; range->openmax[BR_OPTIMTOL] = true; range->min[BR_LAMBDA] = 0; range->max[BR_LAMBDA] = RF_INF; range->pmin[BR_LAMBDA] = 0; range->pmax[BR_LAMBDA] = RF_INF; range->openmin[BR_LAMBDA] = true; range->openmax[BR_LAMBDA] = true; range->min[BR_OPTIMAREA] = 0; range->max[BR_OPTIMAREA] = 1; range->pmin[BR_OPTIMAREA] = 0; range->pmax[BR_OPTIMAREA] = 1; range->openmin[BR_OPTIMAREA] = false; range->openmax[BR_OPTIMAREA] = false; range->min[BR_OPTIMMAX] = 1; range->max[BR_OPTIMMAX] = RF_INF; range->pmin[BR_OPTIMMAX] = 1000; range->pmax[BR_OPTIMMAX] = 1000000000; range->openmin[BR_OPTIMMAX] = false; range->openmax[BR_OPTIMMAX] = true; range->min[BR_VARIOBOUND] = 0; range->max[BR_VARIOBOUND] = RF_INF; range->pmin[BR_VARIOBOUND] = 2; range->pmax[BR_VARIOBOUND] = 25; range->openmin[BR_VARIOBOUND] = false; range->openmax[BR_VARIOBOUND] = true; } int structBRuser(cov_model *cov, cov_model **newmodel) { location_type *loc = Loc(cov); cov_model *sub = cov->sub[cov->sub[MPP_SHAPE] != NULL ? MPP_SHAPE: MPP_TCF]; int i, d, err, model_intern, dim = sub->tsdim, newxlen; bool grid; double centreloc[MAXMPPDIM], minloc[MAXMPPDIM], maxloc[MAXMPPDIM], *newx= NULL, **xgr = loc->xgr; ASSERT_NEWMODEL_NULL; if (cov->role != ROLE_BROWNRESNICK) BUG; assert(isBRuserProcess(cov)); if (loc->Time || (loc->grid && loc->caniso != NULL)) { Transform2NoGrid(cov, false, GRIDEXPAND_AVOID, false); SetLoc2NewLoc(sub, PLoc(cov)); } loc = Loc(cov); grid = loc->grid; model_intern = (cov->nr == BRORIGINAL_USER) ? BRORIGINAL_INTERN : (cov->nr == BRMIXED_USER) ? BRMIXED_INTERN : (cov->nr == BRSHIFTED_USER) ? BRSHIFTED_INTERN : BRORIGINAL_USER; if (cov->key != NULL) COV_DELETE(&(cov->key)); if (cov->Sgen == NULL) NEW_STORAGE(gen); GetDiameter(loc, minloc, maxloc, centreloc); newxlen = loc->lx; if ((newx = (double*) MALLOC(dim * newxlen * sizeof(double))) == NULL) { GERR("Memory allocation failed.\n"); } if (grid) { for (d=0; dlx; i++) for(d=0; dx[i*dim+d] - centreloc[d]; } if ((err = loc_set(newx, NULL, dim, dim, newxlen, false, loc->grid, loc->distances, cov)) > NOERROR) goto ErrorHandling; SetLoc2NewLoc(sub, PLoc(cov)); if ((err=covCpy(&(cov->key), sub)) > NOERROR) goto ErrorHandling; if (cov->sub[MPP_TCF] != NULL) { if ((err = STRUCT(sub, &(cov->key))) > NOERROR) goto ErrorHandling; assert(cov->key->calling == cov); } addModel(&(cov->key), model_intern); kdefault(cov->key, GEV_XI, P0(GEV_XI)); kdefault(cov->key, GEV_MU, P0(GEV_MU)); kdefault(cov->key, GEV_S, P0(GEV_S)); if (cov->nr == BRMIXED_USER) { kdefault(cov->key, BR_MESHSIZE, P0(BR_MESHSIZE)); kdefault(cov->key, BR_VERTNUMBER, P0INT(BR_VERTNUMBER)); kdefault(cov->key, BR_OPTIM, P0INT(BR_OPTIM)); kdefault(cov->key, BR_OPTIMTOL, P0(BR_OPTIMTOL)); kdefault(cov->key, BR_VARIOBOUND, P0(BR_VARIOBOUND)); kdefault(cov->key, BR_OPTIMMAX, P0INT(BR_OPTIMMAX)); kdefault(cov->key, BR_LAMBDA, P0(BR_LAMBDA)); if (!PisNULL(BR_OPTIMAREA)) { if ( cov->nrow[BR_OPTIMAREA] % 2 == 0 || cov->ncol[BR_OPTIMAREA] % 2 == 0 ) { SERR("number of rows and columns of areamat need to be odd") } PARAMALLOC(cov->key, BR_OPTIMAREA, cov->nrow[BR_OPTIMAREA], cov->ncol[BR_OPTIMAREA]); PCOPY(cov->key, cov, BR_OPTIMAREA); } } cov->key->calling = cov; if ((err = CHECK(cov->key, dim, dim, PointShapeType, cov->domown, cov->isoown, 1, ROLE_BROWNRESNICK)) == NOERROR) { if ((err = STRUCT(cov->key, NULL)) <= NOERROR) { err = CHECK(cov->key, dim, dim, PointShapeType, cov->domown, cov->isoown, 1, ROLE_BROWNRESNICK); } } assert(cov->key->calling == cov); ErrorHandling: FREE(newx); return err; } // new int structBRintern(cov_model *cov, cov_model **newmodel) { cov_model *sub = cov->sub[cov->sub[MPP_SHAPE] != NULL ? MPP_SHAPE: MPP_TCF]; location_type *loc = Loc(cov); int i, d, j, err, dim = sub->tsdim, totaldim = loc->totalpoints*dim, zeropos = 0, // default, mostly overwritten newxlen = 3; // default (grid) bool grid = loc->grid; double norm, step, mindist, dist, **xgr = loc->xgr; br_storage *sBR = NULL; ASSERT_NEWMODEL_NULL; if (cov->role != ROLE_BROWNRESNICK) BUG; assert(isPointShape(cov)); if (cov->key != NULL) COV_DELETE(&(cov->key)); if (cov->Sgen == NULL) NEW_STORAGE(gen); NEW_STORAGE(br); sBR = cov->Sbr; if (cov->sub[MPP_TCF] != NULL) { if ((err = STRUCT(sub, &(cov->key))) > NOERROR) goto ErrorHandling; cov->key->calling = cov; } else if ((err=covCpy(&(cov->key), sub)) > NOERROR) goto ErrorHandling; if ((err = CHECK(cov->key, dim, dim, VariogramType, cov->domown, SYMMETRIC, 1, ROLE_COV)) != NOERROR) goto ErrorHandling; if ((err = covCpy(&(sBR->submodel), cov->key)) != NOERROR) goto ErrorHandling; if ((err = CHECK(sBR->submodel, 1, 1, VariogramType, XONLY, ISOTROPIC, 1, ROLE_COV)) != NOERROR) goto ErrorHandling; if ((err = newmodel_covCpy(&(sBR->vario), VARIOGRAM_CALL, cov->key))!=NOERROR) goto ErrorHandling; if ((err = alloc_cov(sBR->vario, dim, 1, 1)) != NOERROR) goto ErrorHandling; addModel(&(cov->key), GAUSSPROC, cov); assert(cov->key->ownloc == NULL); if (cov->nr == BRORIGINAL_INTERN) { if (!grid) { zeropos = loc->lx; for (i=0; ilx; i++) { norm = 0.0; for (d=0; dx[i*dim+d]*loc->x[i*dim+d]; } if (norm<1e-8) zeropos = i; } newxlen = loc->lx + (zeropos == loc->lx); if ((sBR->newx = (double*) MALLOC(dim*newxlen*sizeof(double))) == NULL) { err=ERRORMEMORYALLOCATION; goto ErrorHandling; } for(d=0; dlx; i++) sBR->newx[i*dim+d] = loc->x[i*dim+d]; if (zeropos == loc->lx) sBR->newx[loc->lx*dim+d] = 0.0; } } } else if (cov->nr == BRMIXED_INTERN) { step = P0(BR_MESHSIZE); mindist = RF_INF; if (grid) { for (d=0; d 1000) { warning("minimal distance is only estimated"); maxtotal = 1000; // to do } for (i=0; ix[i+d] - loc->x[j]); if (dist > 1e-15 && dist < mindist) mindist = dist; } } if (mindist < step) { PRINTF("Warning! meshsize is larger than resolution of simulation! meshsize is automatically decreased to %f.\n", step); P(BR_MESHSIZE)[0] = step = mindist; } if (!PisNULL(BR_OPTIMAREA)) { sBR->minradius = floor(fmax(cov->nrow[BR_OPTIMAREA], cov->ncol[BR_OPTIMAREA])*0.5) * step; } double alpha = -1, yy, C0, gammamin, min_radius, xx=step * 1e-6; COV(ZERO, sBR->submodel, &C0); COV(&xx, sBR->submodel, &yy); alpha = log(C0 - yy) / log(xx); if (alpha > 2.0) alpha = 2.0; gammamin = 4.0 - 1.5 * alpha; INVERSE(&gammamin, sBR->submodel, &min_radius); xx = gammamin + P0(BR_VARIOBOUND); INVERSE(&xx, sBR->submodel, sBR->radii); sBR->radii[0] = ceil(sBR->radii[0] / step) * step; if (sBR->minradius > sBR->radii[0]) sBR->radii[0] = sBR->minradius; sBR->thresholds[0] = RF_INF; newxlen = 3; grid = true; double smallest_grid_len = 3.0, //kleinestes Feld, dass simuliert werden // soll, in step Einheiten in 1 koordinaten richtung min_radius_step = floor(min_radius / step), onesided = (double) (smallest_grid_len - 1) * 0.5; if (onesided < min_radius_step) onesided = min_radius_step; double corrected_minradius = sBR->minradius + GLOBAL.br.corr_factor * (sBR->radii[0] - sBR->minradius); if (onesided * step < corrected_minradius) onesided = floor(corrected_minradius / step); // MARCO: @MARTIN: um sicherzugehen, dass man den durch areamat abgedeckten // Bereich komplett simuliert double min_reduction_factor = 2.0, max_reduction_factor = 3.0, rel_steps = (sBR->radii[0] / step) / onesided, reduction_factor = pow(rel_steps, (double) dim / ((double) MAXSUB -1.0)); if (reduction_factor < min_reduction_factor) reduction_factor = min_reduction_factor; else if (reduction_factor > max_reduction_factor) reduction_factor = max_reduction_factor; sBR->maxidx = (int) ((double) dim * log(rel_steps) / log(reduction_factor)); if (sBR->maxidx < 0) sBR->maxidx = 0; // to do!! else if (sBR->maxidx >= MAXSUB) sBR->maxidx = MAXSUB - 1; for (i=1; i<=sBR->maxidx; i++) { // to do gleichmaessige reduktion ist vermutlich nicht optimal // mitte vermutlich groessere Schritte und dafuer kleiner runter // bis zum minimum. // to do optimale groesse fuer reduction_factor z.Zt. in [2,3]?! sBR->radii[i] = round(sBR->radii[i-1] * pow(2.0, -1.0/dim) / step) * step; COV(sBR->radii + i, sBR->submodel, sBR->thresholds + i); } if ((sBR->newx = (double*) MALLOC(newxlen*dim*sizeof(double))) == NULL) { err = ERRORMEMORYALLOCATION; goto ErrorHandling; } for (i=0; i<=sBR->maxidx; i++) { if ((err = covCpy(sBR->sub + i, cov->key)) != NOERROR) goto ErrorHandling; for (d=0; dnewx[3*d+XSTART] = -sBR->radii[i]; sBR->newx[3*d+XLENGTH] = 2 * ((int) round(sBR->radii[i] / step)) + 1; sBR->newx[3*d+XSTEP] = step; } err = loc_set(sBR->newx, NULL, dim, dim, newxlen, false, grid, false, sBR->sub[i]); double **subxgr = Loc(sBR->sub[i])->xgr; for (zeropos = 0, d = dim; d > 0; d--) { double len = subxgr[d-1][XLENGTH]; zeropos = zeropos * (int) len + (int) ceil(len * 0.5) - 1; } sBR->zeropos[i] = zeropos; if ((err = CHECK(sBR->sub[i], dim, dim, ProcessType, cov->domown, cov->isoown, 1, ROLE_GAUSS)) == NOERROR) { if ((err = STRUCT(sBR->sub[i], NULL)) <= NOERROR) { err = CHECK(sBR->sub[i], dim, dim, ProcessType, cov->domown, cov->isoown, 1, ROLE_GAUSS); } } if (err > NOERROR) goto ErrorHandling; assert(sBR->sub[i]->calling == cov); } goto ErrorHandling; // ueberspringe immer den shifted & original teil ! } else { // END BRMIXED; START SHIFTED assert(cov->nr == BRSHIFTED_INTERN); } if (sBR->newx == NULL) { if ((err = loc_set(grid ? * loc->xgr : loc->x, NULL, dim, dim, grid ? 3 : loc->totalpoints, false, grid, loc->distances, cov->key)) != NOERROR) goto ErrorHandling; } else { if ((err = loc_set(sBR->newx, NULL, dim, dim, newxlen, false, grid, false, cov->key)) != NOERROR) goto ErrorHandling; } xgr = loc->xgr; // ONLY SHIFTED AND ORIGINAL if (grid) { double **subxgr = Loc(cov->key)->xgr; for (d=dim; d>0; d--) { double len = subxgr[d-1][XLENGTH]; zeropos = zeropos * len + (int) ceil(len * 0.5) - 1; } } sBR->zeropos[0] = zeropos; if ((err = CHECK(cov->key, dim, dim, ProcessType, cov->domown, cov->isoown, 1, ROLE_GAUSS)) == NOERROR) { if ((err = STRUCT(cov->key, NULL)) <= NOERROR) { err = CHECK(cov->key, dim, dim, ProcessType, cov->domown, cov->isoown, 1, ROLE_GAUSS); } } if (err > NOERROR) goto ErrorHandling; assert(cov->key->calling == cov); ErrorHandling: if (err != NOERROR) br_DELETE(&(cov->Sbr)); return err; } int structBrownResnick(cov_model *cov, cov_model **newmodel) { int d, err, meth, role, dim = cov->tsdim; double maxcov, minloc[MAXMPPDIM], maxloc[MAXMPPDIM], centreloc[MAXMPPDIM], maxdist[MAXMPPDIM]; cov_model *next = cov->sub[0]; location_type *loc = Loc(cov); if (cov->role != ROLE_BROWNRESNICK) BUG; if (loc->Time || (loc->grid && loc->caniso != NULL)) { Transform2NoGrid(cov, false, GRIDEXPAND_AVOID, false); SetLoc2NewLoc(next, PLoc(cov)); } loc = Loc(cov); if (cov->tsdim != cov->xdimprev || cov->tsdim != cov->xdimown) return ERRORDIM; if (cov->key != NULL) COV_DELETE(&(cov->key)); if (cov->role == ROLE_SMITH) { if (!cov->logspeed) SERR2("'%s' requires a variogram model as submodel that tends to infinity with rate of at least 4log(h) for being compatible with '%s'", NICK(cov), CovList[SMITHPROC].nick); cov_model *calling = cov->calling; double newscale, factor = INVSQRTTWO; ASSERT_NEWMODEL_NULL; if (next->full_derivs < 0) SERR("given submodel does not make sense"); while (isDollar(next)) { addModel(&(cov->key), DOLLAR); newscale = 1.0; if (!PARAMisNULL(next, DSCALE) ) newscale *= PARAM0(next, DSCALE); if (!PARAMisNULL(next, DVAR) ) newscale /= sqrt(PARAM0(next, DVAR)); if (factor != 1.0) { newscale *= factor; factor = 1.0; } return ERRORNOTPROGRAMMEDYET; kdefault(calling, DSCALE, newscale); next = next->sub[0]; // ok } if (cov->sub[MPP_TCF] != NULL) { return ERRORNOTPROGRAMMEDYET; } if (next->nr == BROWNIAN && PARAM0(next, BROWN_ALPHA) == 2.0) { addModel(&(cov->key), GAUSS); // ?? if (factor != 1.0) { addModel(&(cov->key), DOLLAR); kdefault(cov->key, DSCALE, factor); } } else { SERR("Smith process with BrownResnick tcf only possible for fractal Brownian motion with alpha=2"); } } else if (cov->role == ROLE_BROWNRESNICK) { if (next->role == ROLE_BROWNRESNICK) { SERR1("submodel of '%s' must be a covariance model or tcf", NICK(cov)); } else { role = isVariogram(next) ? ROLE_COV : ROLE_UNDEFINED; ASSERT_ROLE_DEFINED(next); if (((err = covCpy(&(cov->key), next)) != NOERROR) || ((err = CHECK(cov->key, dim, dim, VariogramType, XONLY, SYMMETRIC, 1, role)) != NOERROR)) { return err; } GetDiameter(loc, minloc, maxloc, centreloc); for (d=0; dkey, maxdist, NULL, NULL, dim, dim, 1, 0, false, false, false)) != NOERROR) return err; if ((err = alloc_cov(K, dim, 1, 1)) != NOERROR) return err; if (K->sub[0] != NULL) SetLoc2NewLoc(K->sub[0], PLoc(K)); Variogram(NULL, K, &maxcov); COV_DELETE(&K); if (isPosDef(next) || maxcov <= 4.0) { meth = BRORIGINAL_USER; } else if (!next->logspeed || next->logspeed <= 4.0 || maxcov <= 10.0) { meth = BRSHIFTED_USER; } else { meth = BRMIXED_USER; } addModel(&(cov->key), meth, cov); cov_model *key = cov->key; key->prevloc = PLoc(cov); kdefault(key, GEV_XI, P0(GEV_XI)); kdefault(key, GEV_MU, P0(GEV_MU)); kdefault(key, GEV_S, P0(GEV_S)); if ((err = CHECK(key, dim, dim, BrMethodType, cov->domown, cov->isoown, 1, ROLE_BROWNRESNICK)) == NOERROR) { if ((err = STRUCT(key, NULL)) <= NOERROR) { err = CHECK(key, dim, dim, BrMethodType, cov->domown, cov->isoown, 1, ROLE_BROWNRESNICK); } } if (err > NOERROR) return(err); } } else { ILLEGAL_ROLE; } // need check to be called? return NOERROR; } int initBrownResnick (cov_model *cov, gen_storage *S) { cov_model *sub = cov->key != NULL ? cov->key : cov->sub[cov->sub[MPP_SHAPE] != NULL ? MPP_SHAPE: MPP_TCF]; int err; assert(cov->nr == BROWNRESNICKPROC); if (cov->role == ROLE_BROWNRESNICK) { if (cov->key != NULL) { sub->simu.active = true; sub->simu.expected_number_simu = cov->simu.expected_number_simu; if ((err = INIT(sub, 0, S)) != NOERROR) return err; cov->fieldreturn = true; cov->origrf = false; cov->rf = sub->rf; } } else ILLEGAL_ROLE; return NOERROR; } void doBrownResnick(cov_model *cov, gen_storage *s) { assert(!cov->origrf); assert(cov->key != NULL); cov_model *key = cov->key; PL++; DO(key, s); // nicht gatternr PL--; } int initBRuser (cov_model *cov, gen_storage *S) { location_type *loc = Loc(cov); cov_model *sub = cov->key != NULL ? cov->key : cov->sub[cov->sub[MPP_SHAPE] != NULL ? MPP_SHAPE: MPP_TCF]; int err, maxpoints = GLOBAL.extreme.maxpoints; assert(isBRuserProcess(cov)); if (cov->role == ROLE_BROWNRESNICK) { if (loc->distances) return ERRORFAILED; if (cov->key != NULL) { sub->simu.active = true; double ens = ((double) cov->simu.expected_number_simu) * maxpoints; sub->simu.expected_number_simu = (int) MIN(ens, (double) MAXINT); if ((err = INIT(sub, 1, S)) != NOERROR) return err; FieldReturn(cov); } return NOERROR; } else ILLEGAL_ROLE; }