/* Authors Martin Schlather, martin.schlather@math.uni-goettingen.de main library for unconditional simulation of random fields Copyright (C) 2001 -- 2003 Martin Schlather Copyright (C) 2004 -- 2004 Yindeng Jiang & Martin Schlather 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. */ /* PRINTING LEVELS =============== error messages: 1 forcation : 2 minor tracing information : 3--5 large debugging information: >10 */ /* calculate the transformation of the points only once and store the result in a register (indexed by ncov) of key, not of s->. Advantages: points have to calculated only once for several tries; if zonal anisotropy then specific methods may be called; */ #include #include #include //#include #include #include "RF.h" #include #include #include "Covariance.h" /* in CheckCovariance and other the following dimensions are used: xdim : dimension of the points given by the user. value is <= timespacedim since in case of isotropy only the distances might be given by the user timespacedim : (= kc->dim = key->timespacedim) the true dimension for the location (if necessary by explicite parameter, e.g. in CovarianceFct.) anisodim : vector of dimensions given by the user in the definition of the covariance function (by the dimension of the anisotropy matrix); could be less than timespacedim in case of isotropic covariance functions; the value is always less than or equal to timespacedim; it can be less than timespacedim only in submodels of hypermodels */ SEXP getListElement(SEXP list, char *str) { SEXP elmt = R_NilValue, names = getAttrib(list, R_NamesSymbol); int i; if (names == R_NilValue) { return R_NilValue; } for (i = 0; i < LENGTH(names); i++) { if(strcmp(CHAR(STRING_ELT(names, i)), str) == 0) { elmt = VECTOR_ELT(list, i); break; } } return elmt; } int getListEltNr(SEXP list,const char *str) { // == -1 if no matching name is found // == -2 if multiple matching fctns are found, without one matching exactly SEXP names = getAttrib(list, R_NamesSymbol); if (names == R_NilValue) return NOMATCHING; unsigned int ln; int Nr=0, i, n=LENGTH(names); ln=strlen(str); while ( Nr < n && strncmp(str, CHAR(STRING_ELT(names, Nr)), ln)) Nr++; if (Nr < n) { if (ln==strlen(CHAR(STRING_ELT(names, Nr)))) { for (i=Nr+1; i < n; i++) { if (strncmp(str, CHAR(STRING_ELT(names, i)), ln) == 0) { return MULTIPLEMATCHING; } } return Nr; } // a matching function is found. Are there other functions that match? int j; bool multiplematching=false; j=Nr+1; // if two or more covariance functions have the same name // the last one is taken while (jp[i] != NULL) { if (next->ncol[i] != 1 || next->nrow[i] != 1) { char MSG[255]; sprintf(MSG, "%s is not a scalar", name); ERR(MSG); } if (cov->p[i] == NULL) { cov->p[i] = (double*) malloc(sizeof(double)); cov->ncol[i] = cov->nrow[i] = 1; cov->p[i][0] = next->p[i][0]; cov->ncol[i] = cov->nrow[i] = 1; } else cov->p[i][0] *= next->p[i][0]; } } void includeparam(void **qq, SEXPTYPE type, int len, SEXP p, int base, char *param_name) { int j; switch(type) { case REALSXP : { double *q; *qq = malloc(sizeof(double) * len); q = (double *) *qq; switch(TYPEOF(p)) { case REALSXP : for (j=0; j MAXELEMENTS) PERR("to223o many list elements"); *qq = malloc(sizeof(listoftype)); q=(listoftype*) (*qq); for (i=0; ip[i] = NULL; q->ncol[i] = 0; q->nrow[i] = 0; } for (i=0; ip + i), REALSXP, LENGTH(pi), pi, base, param_name); // printf("ncol/nrow %d %d %d\n ", ncols(pi), nrows(pi), isMatrix(pi)); if (isMatrix(pi)) { // Achtung isVector ist true falls isMatrix true q->ncol[i] = ncols(pi); q->nrow[i] = nrows(pi); } else if (isVector(pi)) { q->ncol[i] = 1; q->nrow[i] = LENGTH(pi); } else { PERR("list element(s) neither vector nor matrix"); } } } break; default : PERR("unmatched internal type of parameter"); } } void includeparam(void **qq, SEXPTYPE type, int len, SEXP p, char *param_name) { includeparam(qq, type, len, p, 0, param_name); } void CMbuild(SEXP model, int level, cov_model **Cov, cov_model *previous) { int covnr, i, j, nkappas, methNr, elt=0, len = length(model); char format[30], name[MAXCHAR], param_name[PARAMMAXCHAR], ERR_LOC[nErrorLoc], methname[METHODMAXCHAR], msg[200]; SEXP m, p, names = getAttrib(model, R_NamesSymbol); cov_fct *C; cov_model *cov; bool subleft[MAXSUB]; //, True=true, False=false; // printf("hier\n"); if (TYPEOF(model) != VECSXP) { // not list ERR("list expected") } PROTECT(m = VECTOR_ELT(model, elt++)); if (!isString(m)) ERR("first element must be the name of a covariance model"); if (LENGTH(m) != 1) ERR("model name must be a single word"); strcopyN(name, (char*) CHAR(STRING_ELT(m, 0)), MAXCHAR); // printf("hier %s\n", name); sprintf(format, "%%s\n%%%ds%%s... ", -level); sprintf(ERR_LOC, format, ERROR_LOC, "", name); strcpy(ERROR_LOC, ERR_LOC); covnr = getmodelnr(name); if (covnr == NATSC && NS) ERR("natsc model and RFparameters(PracticalRange=TRUE) may not be given at the same time"); if (covnr == -2) { ERR("multiple matching of covariance name") } else if (covnr == -1) { ERR("unknown covariance model. type `PrintModelList(TRUE, FALSE)' to get the list of models"); } *Cov = NULL; addModel(Cov, covnr); cov = *Cov; cov->nsub = 0; C=CovList + cov->nr; nkappas = C->kappas; for (i=0; imaxsub; i++) subleft[i] = true; // user defined method #define NUGGET_PREFERENCE 1 // printf(">>> %s\n", C->name); methNr = getListEltNr(model, "me"); if (methNr >= 0) { // printf("methnr=%d\n", methNr); p = VECTOR_ELT(model, methNr); for (i=0; iuser[i] = PREF_NONE; if (covnr == NUGGET) cov->user[Nugget] = NUGGET_PREFERENCE; cov->user[Nothing] = PREF_BEST; strcopyN(methname, CHAR(STRING_ELT(p, 0)), METHODMAXCHAR); int meth = Match(methname, METHODNAMES, Forbidden + 1); if (meth >= 0) { cov->user[meth] = PREF_BEST; if (meth == MaxMpp) { cov->user[meth] = cov->user[RandomCoin] = PREF_BEST; } else if (meth == ExtremalGauss) { for (i=0; iuser[i] = PREF_BEST; } } else { sprintf(msg, "%s: unknown method\n", methname); ERR(msg) } } else if (methNr == MULTIPLEMATCHING) { ERR("method given twice"); } else { // no method given copy method from calling model if (previous != NULL) { for (i=0; iuser[i] = previous->user[i]; } if (covnr == NUGGET) cov->user[Nugget] = NUGGET_PREFERENCE; } } for ( ; elt < len; elt++) { if (elt == methNr) continue; p = VECTOR_ELT(model, elt); strcopyN(param_name, names == R_NilValue ? "" : CHAR(STRING_ELT(names, elt)), PARAMMAXCHAR); if (isVectorList(p) && isString(VECTOR_ELT(p, 0))) { // submodels if (strcmp(param_name, "") != 0) { // named submodel if ((i = Match(param_name, C->subnames, C->maxsub)) < 0) { i = Match(param_name, STANDARDSUB, MAXSUB); } if (i < 0) { if (PL > 0) { int s; PRINTF("allowed submodel names are: "); if (C->maxsub == 0) PRINTF("(none)"); else for (s=0; smaxsub; s++) { if (s>0) PRINTF(", "); PRINTF("%s", STANDARDSUB[s]); if (strcmp(STANDARDSUB[s], C->subnames[s]) != 0) { PRINTF("%s", C->subnames[s]); } } PRINTF("\n"); } if (i == MULTIPLEMATCHING) { #define MERR(X) {UERR;sprintf(MSG,"%s\n%s: %s",ERROR_LOC, param_name, X);\ error(MSG);} MERR("multiple matching of submodel names") } else { MERR("unmatched covariance name for submodel") } } } else { for (j=0; j < C->maxsub; j++) { if (subleft[j]) { i = j; break; } } if (j == C->maxsub) { PRINTF("j=%d maxsub=%d\n", j, C->maxsub); ERR("too many submodels"); } } if (!subleft[i]) { MERR("submodel given twice"); } else subleft[i] = false; CMbuild(p, level + 1, cov->sub + i, cov); cov->sub[i]->calling = cov; (cov->nsub)++; } else { // parameter (not list) // parameter identification int l = LENGTH(p); if (param_name[0]=='k' && strlen(param_name) == 1) { if (l != C->kappas) ERR("length of vector does not match number of parameters. Do not use short name 'k' in complex situtations either."); if (C->maxsub!=0) ERR("short form 'k' of parameter name not allowed for sophistacted models"); if (cov->p[0] != NULL) ERR("parameter given twice"); for (j=0; jncol[j] = cov->nrow[j] = 1; includeparam((void**) (cov->p + j), C->kappatype[j], 1, p, j, param_name); } break; } if (strcmp(param_name, "") == 0) { if (nkappas == 1) i = 0; else ERR("parameters must be named"); } else { if ((i = Match(param_name, C->kappanames, nkappas)) < 0) { i = Match(param_name, STANDARDPARAM, MAXPARAM); } if (i < 0) { if (PL > 0) { int s; PRINTF("allowed parmeter names are: "); if (C->kappas == 0) PRINTF("(none)"); else for (s=0; smaxsub; s++) { if (strcmp("", C->kappanames[s]) != 0) PRINTF("%s, ", C->kappanames[s]); PRINTF("%s, ", STANDARDPARAM[s]); } PRINTF("\n"); } if (i == MULTIPLEMATCHING) PERR("multiple matching of parameter"); if (i == NOMATCHING){ PERR("unknown parameter"); } } } if (cov->p[i] != NULL) ERR("parameter given twice"); // printf("include %d %d %s\n", i, C->kappatype[i], param_name); includeparam((void**) (cov->p + i), C->kappatype[i], l, p, param_name); if (C->kappatype[i] > LISTOF && TYPEOF(p) != VECSXP) { if (isMatrix(p) || isVector(p)) { cov->ncol[i] = cov->nrow[i] = 1; } else { PERR("not a list of vectors or matrices"); } } else { if (isMatrix(p)) { // Achtung isVector ist true falls isMatrix true cov->ncol[i] = ncols(p); cov->nrow[i] = nrows(p); } else if (isVector(p)) { cov->ncol[i] = 1; cov->nrow[i] = LENGTH(p); } else { PERR("neither vector nor matrix"); } } } } for (j=0; j < C->maxsub; j++) if (subleft[j]) break; if (j < C->maxsub) { if (j < C->minsub) { // if (PL > 3) PrintModelInfo(cov); ERR("not enough submodels"); } if (PL > 1) { for ( ; j < C->maxsub; j++) if (!subleft[j]) break; if (j < C->maxsub) {warning("not all submodels are given");} } } // PrintModelInfo(cov); if (NS > 0 && NS != NATSCALE_MLE && C->naturalscale != NULL) { // if NS but not from MLE, then add natscale whenever primitive visible addModel(Cov, GATTER); addModel(Cov, NATSC); } else { if (NS == NATSCALE_MLE && cov->nr >= DOLLAR && cov->nr <= LASTDOLLAR && CovList[cov->sub[0]->sub[0]->nr].naturalscale != NULL) { bool natsc; double *pp; // printf("---> %s\n", CovList[cov->sub[0]->sub[0]->nr].name); // PrintModelInfo(cov); pp = cov->p[DSCALE]; natsc = pp != NULL && (ISNA(pp[0]) || ISNAN(pp[0])); if (!natsc && pp == NULL) { int i, total = cov->ncol[DANISO] * cov->nrow[DANISO]; natsc = true; pp = cov->p[DANISO]; for (i=0; isub[0]->sub; addModel(nextaftergatter, GATTER); addModel(nextaftergatter, NATSC); } // PrintModelInfo(cov); assert(false); } } addModel(Cov, GATTER); UNPROTECT(1); } void DeleteGatter(cov_model **Cov) { cov_model *cov = *Cov; if (cov->nr >= GATTER && cov->nr <= LASTGATTER && cov->tsdim <= DEL_COV) { removeOnly(Cov); DeleteGatter(Cov); } else { int i; for (i=0; isub[i] != NULL) DeleteGatter(cov->sub + i); } } void checkerror(int err){ char EM[300+2*MAXERRORSTRING], EM2[300+2*MAXERRORSTRING]; errorMSG(err, EM); sprintf(EM2, "%s\n ...%s", ERROR_LOC, EM); error(EM2); } void CheckModelInternal(SEXP model, int tsdim, int xdim, bool stationary, cov_model **Cov, int MaxDim) { int err, PL = GLOBAL.general.printlevel; if (*Cov != NULL) { COV_DELETE(Cov); } if (currentNrCov==-1) InitModelList(); if (tsdim < 1 || tsdim > MaxDim || xdim > tsdim) { checkerror(ERRORDIM); } strcpy(ERROR_LOC, "Checking model at "); CMbuild(model, 0, Cov, NULL); if (PL>6) PRINTF("detected model structure is:\n%s\n", ERROR_LOC); strcpy(ERROR_LOC, ""); if (PL > 6) { PRINTF("\nCheckModelInternal, before checking:"); PrintModelInfo(*Cov); // OK } cov_model *cov= *Cov; if (cov != NULL) { assert(cov->nr >= GATTER && cov->nr<=LASTGATTER); cov->calling=NULL; cov->tsdim = tsdim; cov->xdim = xdim; cov->statIn = stationary ? STATIONARY : PREVMODELS; if ((err = CovList[cov->nr].check(cov)) != NOERROR) { PRINTF("err =%d\n", err); XERR(err); } DeleteGatter(Cov); cov = *Cov; } // else if (PL > 6) { PRINTF("CheckModelInternal, after checking:"); PrintModelInfo(*Cov); // OK } } void CheckModel(SEXP model, SEXP tsdim, SEXP xdim, SEXP stationary, cov_model **Cov, int MaxDim) { // assert(INTEGER(tsdim)[0] == 3); CheckModelInternal(model, INTEGER(tsdim)[0], INTEGER(xdim)[0], LOGICAL(stationary)[0], Cov, MaxDim); } void strround(double x, char *s){ if (x==RF_INF) sprintf(s, "Inf"); else if (x==RF_NEGINF) sprintf(s, "-Inf"); else if (x == floor(x + 0.5)) sprintf(s, "%d", (int) x); else sprintf(s, "%f", x); } void addmsg(double value, const char *sign, double y, char *msg) { char str1[30], str2[30]; strround(value, str1); strround(y, str2); sprintf(msg, "%s %s %s", str1, sign, str2); } void addone(char *str, double x) { char str2[30]; strround(x, str2); sprintf(str, "%s, %s", str, str2); } void addpair(char *str, double x, double y) { if (x == floor(x + 0.5) && y==floor(y + 0.5)) sprintf(str, "%s, (%d,%d)", str, (int) x, int(y)); else sprintf(str, "%s, (%f,%f)", str, x, y); } void range_default(range_arraytype *ra) { ra->n = 1; range_type *range = ra->ranges; range->maxdim = INFDIM; range->finiterange = false; } int check_within_range(cov_model *cov, bool NAOK) { // sets also maxdim and finiterange in cov ! cov_fct *C = CovList + cov->nr; int n, len, err = NOERROR, k = 0, i = 0, // compiler dummy values kappas = C->kappas; range_arraytype ra; SEXPTYPE *type = C->kappatype; rangefct getrange = C->range; char msg[255]=""; double min, max, value= RF_NAN; if (GLOBAL.general.skipchecks) return NOERROR; range_default(&ra); // default : 1 range; maxdim = inf // printf("%s %ld %ld\n", C->name, C->cov, C->range); getrange(cov, &ra); cov->finiterange = ra.ranges[0].finiterange; if (kappas == 0) { if ((cov->maxdim = ra.ranges[0].maxdim) < cov->tsdim) { if (PL>4) PRINTF("max dim is %d %d \n", ra.ranges[0].maxdim, cov->tsdim); sprintf(msg, "Max. dimension is %d. Got %d.\n", ra.ranges[0].maxdim, cov->tsdim); err = ERRORCOVNOTALLOWED; goto ErrorHandling; } } else { char Msg[255]; range_type *range = ra.ranges; for(n=0; nmin[0], range->max[0]); if ((cov->maxdim = range->maxdim) < cov->tsdim) { if (ra.n == 1) { sprintf(msg, "max dim is %d. Got %d.", range->maxdim, cov->tsdim); err = ERRORFAILED; break; } else { sprintf(msg, "unspecified"); err = ERRORFAILED; continue; } } err = NOERROR; for (i=0; i= LISTOF) { // to simplify things -- otherwise in simu.cc // code must also be changed. assert(range->min[i] == RF_NEGINF && range->max[i]==RF_INF); continue; } // full range !! len=cov->ncol[i] * cov->nrow[i]; min = range->min[i]; max = range->max[i]; // printf("%s ra %d i=%d n=%d %f %f \n", // C->name, ra.n, i, n, range->min[i], range->max[i]); // min = -RF_INF; for (k=0; kp[i][k]; else if (type[i] == INTSXP) value = ((int *)cov->p[i])[k] == NA_INTEGER ? NA_REAL : (double) ((int *)cov->p[i])[k]; else error("parameter value of unknown SXP type"); if (ISNA(value) || ISNAN(value)) { if (NAOK) { continue; } else { sprintf(Msg, "%f : finiteness", value); err = ERRORUNSPECIFIED; break; } } // printf("range %d %d %d op=%d %f %f %f\n", // kappas, i, k, range->openmin[i], value, min, max); if (range->openmin[i] && value <= min) { addmsg(value, ">", min, Msg); break; } else if (value < min) { addmsg(value, ">=", min, Msg); break; } if (range->openmax[i] && value >= max) { addmsg(value, "<", max, Msg); break; } else if (value > max) { addmsg(value, "<=", max, Msg); break; } } if (k < len) { err = ERRORUNSPECIFIED; break; } } if (err == NOERROR) break; } // ra.n if (err != NOERROR) { PRINTF("--- %d %s %d %d %d %d\n", n, C->name, i, n, ra.n, err); if (err != ERRORFAILED) sprintf(msg, "%s[%d] = %s does not hold (dim=%d).", C->kappanames[i], k+1, Msg, cov->tsdim); err = ERRORFAILED; goto ErrorHandling; } } cov->normalmix = cov->maxdim == INFDIM; ErrorHandling: if (err!=NOERROR) ERR(msg); return err; } void get_internal_ranges(cov_model *cov, cov_model *min, cov_model *max, cov_model *openmin, cov_model *openmax, bool practical) { cov_fct *C = CovList + cov->nr; int n, err = NOERROR, k = 0, i = 0, // compiler dummy values kappas = C->kappas ; range_arraytype ra; rangefct getrange = C->range; SEXPTYPE *type = C->kappatype; if (kappas > 0) { range_default(&ra); getrange(cov, &ra); cov->finiterange = ra.ranges[0].finiterange; range_type *range = ra.ranges; for(n=0; nmaxdim < cov->tsdim) { assert(ra.n > 1); continue; } err = NOERROR; for (i=0; incol[i] * cov->nrow[i]; double dmin, dmax, dopenmin, dopenmax, value = RF_NAN; if (practical) { dmin = range->pmin[i]; dmax = range->pmax[i]; dopenmin = dopenmax = 0.0; // printf("range %s %f %f\n", CovList[cov->nr].name, dmin, dmax); } else { dmin = range->min[i]; dmax = range->max[i]; dopenmin = 1.0 * (double) range->openmin[i]; dopenmax = 1.0 * (double) range->openmax[i]; } for (k=0; kp[i][k]; min->p[i][k] = dmin; max->p[i][k] = dmax; openmin->p[i][k] = dopenmin; openmax->p[i][k] = dopenmax; } else if (type[i] == INTSXP) { value = ((int *)cov->p[i])[k] == NA_INTEGER ? NA_REAL : (double) ((int *)cov->p[i])[k]; ((int *) min->p[i])[k] = (int) dmin; ((int *) max->p[i])[k] = (int) dmax; ((int *) openmin->p[i])[k] = (int) dopenmin; ((int *) openmax->p[i])[k] = (int) dopenmax; } else if (type[i] == LISTOF + REALSXP) { listoftype *p = (listoftype*) min->p[i]; int j, lenj = p->nrow[k] * p->ncol[k]; double *pmin = ((listoftype*) max->p[i])->p[k], *pmax = ((listoftype*) max->p[i])->p[k], *omin = ((listoftype*) openmin->p[i])->p[k], *omax = ((listoftype*) openmax->p[i])->p[k]; for (j=0; jmin[i]; dmax = range->max[i]; if (value < dmin || value > dmax || (range->openmin[i] && value == dmin) || (range->openmax[i] && value == dmax) ) break; } if (k < len) { err = ERRORDUMMY; break; } } if (err == NOERROR) break; } // ra.n assert(err == NOERROR); } // if (kappa > 0) for (i=0; isub[i] != NULL) { get_internal_ranges(cov->sub[i], min->sub[i], max->sub[i], openmin->sub[i], openmax->sub[i], practical); } } } void get_ranges(cov_model *cov, cov_model **min, cov_model **max, cov_model **openmin, cov_model **openmax, bool practical) { // returns a reliable value only in the very first // entry of each parameter vector/matrix covcpy(min, cov, false, true); covcpy(max, cov, false, true); covcpy(openmin, cov, false, true); covcpy(openmax, cov, false, true); get_internal_ranges(cov, *min, *max, *openmin, *openmax, practical); } void Covariance(double *x, double *y, int lx, cov_model *cov, int idx, double *value) { int vsq = cov->vdim * cov->vdim, xdim = cov->xdim; if (cov->pref[Nothing] == 0 || (cov->statIn != STATIONARY && (cov->statIn != COVARIANCE))) { ERR("Covariance cannot be calculated"); } // PrintModelInfo(cov); // CovMatrixIndexActive = idx >= 0; CovMatrixRow = idx; if (y==NULL || (SEXPREC*)y==R_NilValue) { for (CovMatrixCol=0; CovMatrixColnr].cov(x, cov, value + CovMatrixCol * vsq); } } else { for (CovMatrixCol=0; CovMatrixColnr].nonstat_cov(x, y, cov, value + CovMatrixCol * vsq); } //CovMatrixIndexActive = false; //PrintModelInfo(cov); } void CovMulti(double *x, double *y, int lx, cov_model *cov, double *value) { int i, ii, v,j, vdim = cov->vdim, vdimsq = vdim * vdim, vdimlx = vdim * lx, vdim2lx = vdimsq * lx, // vdlxP1 = vdimlx + 1, xdim = cov->xdim, err = NOERROR; double **Val=NULL, *cross=NULL, *z=NULL, *d=x; if ((Val = (double**) malloc(sizeof(double*) * vdimsq)) == NULL){ err = ERRORMEMORYALLOCATION; goto ErrorHandling; } if ((cross= (double*) malloc(sizeof(double) * vdimsq)) == NULL){ err = ERRORMEMORYALLOCATION; goto ErrorHandling; } if ((z= (double*) malloc(sizeof(double) * xdim)) == NULL){ err = ERRORMEMORYALLOCATION; goto ErrorHandling; } // for (i=0;i<1000; i++) { // printf("%d \n", i); // value[i] = 1.0; // } for (v = i = 0; istatIn == STATIONARY) { covfct cf = CovList[cov->nr].cov; CovMatrixCol = - 1; for (CovMatrixRow=0; CovMatrixRowstatIn == COVARIANCE){ nonstat_covfct cf = CovList[cov->nr].nonstat_cov; double *dy=y; for (CovMatrixRow=0; CovMatrixRowvdim > 1) { CovMulti(x, y, lx, cov, value); } else { Covariance(x, y, lx, cov, -1, value); } } void Cov(double *x, double *y, int *lx, double *value) { cov_model *cov = STORED_MODEL[MODEL_USER]; if (cov->vdim > 1) { CovMulti(x, y, *lx, cov, value); } else { Covariance(x, y, *lx, cov, -1, value); } } void CovMatrixMulti(double *x, bool dist, int size, cov_model *cov, double *value) { // geblockt nach variablen -- somit koennen die univariaten // covariance matrizen problemlos ausgelesen werden. // cov->vdim = 4; // hier kann noch etwas beschleunigt werden, dadurch, dasss // die Werte gespiegelt und nciht neu berechnet werden. int i, ii, v, k,j, vdim = cov->vdim, vdimsq = vdim * vdim, vdimsize = vdim * size, sizesqvdim = vdimsize * size, vdimsize2 = vdimsize * vdimsize, // vdsizeP1 = vdimsize + 1, err = NOERROR, xdim = cov->xdim, sizeM1 = size-1; double **Val=NULL, *cross=NULL, *z=NULL, *d; if ((Val = (double**) malloc(sizeof(double*) * vdimsq)) == NULL) { err = ERRORMEMORYALLOCATION; goto ErrorHandling; } if ((cross= (double*) malloc(sizeof(double) * vdimsq)) == NULL){ err = ERRORMEMORYALLOCATION; goto ErrorHandling; } if ((z= (double*) malloc(sizeof(double) * xdim)) == NULL){ err = ERRORMEMORYALLOCATION; goto ErrorHandling; } // printf("%d %d %d dist=%d\n", vdim, vdimsq,xdim, (int) dist); // PrintModelInfo(cov); // assert(false); // print("\n"); // for (i=0; inr].cov; // lower triangle for (CovMatrixCol=0; CovMatrixCol 0.000001); } } } // assert(false); // assert(false); //A: 0 1 size=376 1 2 374 1085485096 //A: 374 375 size=376 1 2 70499 1086049088 // // upper triangle for (CovMatrixCol=0; CovMatrixColnr].nonstat_cov; double *X, *Y; for (Y=x, CovMatrixCol=0; CovMatrixColxdim; long ho; // double *origx = x; if (cov->pref[Nothing] == 0) { ERR("Covariance cannot be calculated (forbidden)."); } if (cov->vdim > 1) { // FEHLT: dort die index-Menge mitzunehmen!! CovMatrixMulti(x, dist, size, cov, value); return; } CovMatrixTotal = 0; if (dist) { covfct cf = CovList[cov->nr].cov; for (CovMatrixCol=0, i=0; CovMatrixColsub[0]->nr, // CovList[cov->sub[0]->nr].name); value[ho] = value[ve]; } } } else { nonstat_covfct cf = CovList[cov->nr].nonstat_cov; double *X, *Y; Y = x; for (CovMatrixCol=0, i=0; CovMatrixColvdim * cov->vdim, xdim = cov->xdim; double *dummy = (double *) malloc(sizeof(double) *vsq), *C0 = (double *) malloc(sizeof(double) *vsq); covfct cf = CovList[cov->nr].cov; cf(ZERO, cov, C0); if (cov->statIn == STATIONARY || cov->statIn == VARIOGRAM) { for (k=i=0; istatIn == COVARIANCE) { error("cov->stationary == COVARIANCE not programmed yet"); } else { error("unvalid stationarity assumption"); } free(C0); free(dummy); } void Variogram(double *x, double *y, int *lx, double *value) { assert((SEXPREC*) y==R_NilValue); CalculateVariogram(x, *lx, STORED_MODEL[MODEL_USER], value); } void VariogramIntern(double *x, double *y, int *lx, double *value) { assert((SEXPREC*) y==R_NilValue); // PrintModelInfo(STORED_MODEL[MODEL_INTERN]); // assert(false); CalculateVariogram(x, *lx, STORED_MODEL[MODEL_INTERN], value); } void VariogramMLE(double *x, double *y, int *lx, double *value) { assert((SEXPREC*) y==R_NilValue); // PrintModelInfo(STORED_MODEL[MODEL_INTERN]); // assert(false); CalculateVariogram(x, *lx, STORED_MODEL[MODEL_MLE], value); } void InitSimulateRF(double *x, double *T, int *spatialdim, /* spatial dim only ! */ int *lx, int *grid, int *Time, int *distr, /* still unused */ int *keyNr, int *expected_number_simu, int *err) { // keyNr : label where intermediate results are to be stored; // can be chosen freely between 0 and MAXKEYS-1 key_type *key = KEY + *keyNr; strcpy(ERROR_LOC, ""); strcpy(PREF_FAILURE, ""); if ((*keyNr<0) || (*keyNr>=MAXKEYS)) { *err=ERRORREGISTER; goto ErrorHandling; } if ((SEXPREC*) x==R_NilValue) { *err=ERRORCOORDINATES; goto ErrorHandling; } *err = internal_InitSimulateRF(x, T, *spatialdim, *lx, (bool) *grid, (bool) *Time, *distr, key, &GLOBAL, *expected_number_simu, STORED_MODEL + MODEL_SIMU); if (*err == NOERROR) return; ErrorHandling: char EM[500], EM2[500 + 100 * Nothing]; key->simu.active=false; errorMSG(*err, EM); sprintf(EM2, "%s%s\n", PREF_FAILURE, EM); ERR(EM2); // does not return ! } int internal_InitSimulateRF(double *x, double *T, int spatialdim, /* spatial dim only ! */ int lx, bool grid, bool Time, int distr, /* still unused */ key_type *key, globalparam *gp, int expected_number_simu, cov_model **COV) { // NOTE: if grid and Time then the Time component is treated as if // it was an additional space component // On the other hand, SPACEISOTROPIC covariance function will // always assume that the last calling component is the time component! char errloc_save[nErrorLoc]; int err, dim; location_type *loc; strcpy(errloc_save, ERROR_LOC); KEY_DELETE_NOTTREND(key); KEY_NULLNOTTREND(key); key->cov = *COV; *COV = NULL; key->simu.distribution=distr; err = loc_set(x, T, spatialdim, lx, Time, grid, &(key->loc), gp); if (err) goto ErrorHandling; memcpy(&(key->gp), gp, sizeof(globalparam)); loc = &(key->loc); dim = loc->timespacedim; if (err) goto ErrorHandling; // muss als 3. stehen // setmethod method_type *meth; meth = key->meth = (method_type*) malloc(sizeof(method_type)); METHOD_NULL(meth); meth->gp = &(key->gp); meth->gpdo = &(key->gpdo); meth->loc = &(key->loc); meth->simu = &(key->simu); meth->cov = key->cov; // oder besser kopieren ?? meth->xdimout = dim; meth->cvar = 1.0; meth->type = TypeDiag; meth->space = meth->sptime = NULL; err = initstandard(meth); if (err) goto ErrorHandling; key->simu.active = true; strcpy(ERROR_LOC, errloc_save); return NOERROR; ErrorHandling: return err; } void AddTrend(int *keyNr, int *n, double *res, int *err) { int i; key_type *key; trend_type *trend; location_type *loc; *err = NOERROR; if ((*keyNr<0) || (*keyNr>=MAXKEYS)) { *err=ERRORKEYNROUTOFRANGE; goto ErrorHandling; } key = &(KEY[*keyNr]); if (!key->simu.active) {*err=ERRORNOTINITIALIZED; goto ErrorHandling;} trend = &(key->trend); loc = &(key->loc); switch (trend->TrendModus) { case TREND_MEAN : if (trend->mean!=0.0) { long int endfor= *n * loc->totalpoints; for(i=0; imean; } break; case TREND_LINEAR : case TREND_FCT : case TREND_PARAM_FCT : default: assert(false); // not programmed yet } return; ErrorHandling: if (PL>0) ErrorMessage(Nothing,*err); return; } void DoPoissonRF(int *keyNr, int *pairs, int *n, double *res, int *err) { // not programmed yet assert(false); } int internal_DoSimulateRF(key_type *key, int nn, res_type *orig_res) { // does not assume that orig_res[...] = 0.0, but it is set simu_type *simu = &(key->simu); long i, vdimtot = key->loc.totalpoints * key->cov->vdim; res_type *res = orig_res; double realeach=0.0; char format[20], back[]="\b\b\b\b\b\b\b\b\b\b\b", prozent[]="%", pch = key->gpdo.general.pch; int ni, digits, err, each=0; method_type *meth=key->meth; memcpy(&(key->gpdo), &GLOBAL, sizeof(globalparam)); if (!simu->active) {err=ERRORNOTINITIALIZED; goto ErrorHandling;} if (nn>1 && pch != '\0') { if (pch == '!') { digits = (nn<900000000) ? 1 + (int) trunc(log((double) nn) / log(10.0)) : 9; back[digits] = '\0'; each = (nn < 100) ? 1 : nn / 100; sprintf(format, "%ss%s%dd", prozent, prozent, digits); } else if (pch == '%') { back[4] = '\0'; realeach = (double) nn / 100.0; each = (nn < 100) ? 1 : (int) realeach; sprintf(format, "%ss%s%dd%ss", prozent, prozent, 3, prozent); } else each = 1; } else each = nn + 1; GetRNGstate(); // PrintMethodInfo(meth); assert(false); for (ni=1; ni<=nn; ni++, res += vdimtot) { R_CheckUserInterrupt(); if (simu->stop) { err=ERRORNOTINITIALIZED; goto ErrorHandling; } if (ni % each == 0) { if (pch == '!') PRINTF(format, back, ni / each); else if (pch == '%') PRINTF(format, back, (int) (ni / realeach), prozent); else PRINTF("%c", pch); } if (meth->compatible) { for (i=0; idomethod != NULL); meth->domethod(meth, res); } // for n PutRNGstate(); if (nn>1 && pch != '\0') { if (pch == '!' || pch == '%') PRINTF("%s", back); else PRINTF("\n"); } return NOERROR; ErrorHandling: PutRNGstate(); simu->active = false; return err; } void DoSimulateRF(int *keyNr, int *n, int *pairs, res_type *res, int *err) { // does not assume that orig_res[...] = 0.0, but it is set int i, internal_n; key_type *key=NULL; simu_type *simu; *err=NOERROR; if ((*keyNr<0) || (*keyNr>=MAXKEYS)) { *err=ERRORKEYNROUTOFRANGE; goto ErrorHandling; } key = &(KEY[*keyNr]); internal_n = *n / (1 + (*pairs!=0)); simu = &(key->simu); if (key->gp.general.printlevel > 7) { // PrintMethodInfo(key->meth); } if (!simu->active) { *err=ERRORNOTINITIALIZED; goto ErrorHandling; } *err = internal_DoSimulateRF(key, internal_n, res); if (*err != NOERROR) goto ErrorHandling; if (*pairs) { res_type * res_pair; long endfor=key->loc.totalpoints * *n / 2 * key->cov->vdim; res_pair = res + endfor; for (i=0; iactive = key->gp.general.storing)) { KEY_DELETE(key); } return; ErrorHandling: if (key!=NULL) { simu->active = false; KEY_DELETE(key); } return; } // nicht in userinterfaces, da zugriff auf user_... und unchecked_...