https://github.com/cran/RandomFields
Tip revision: cb8a32f1ddcfbcce003da5312030ddb4d1d04dc7 authored by Martin Schlather on 10 July 2012, 00:00:00 UTC
version 2.0.57
version 2.0.57
Tip revision: cb8a32f
InternalCov.cc
/*
Authors
Martin Schlather, martin.schlather@math.uni-goettingen.de
Definition of auxiliary correlation functions
Note:
* Never use the below functions directly, but only by the functions indicated
in RFsimu.h, since there is no error check (e.g. initialization of RANDOM)
* VARIANCE, SCALE are not used here
* definitions for the random coin method can be found in MPPFcts.cc
* definitions for genuinely anisotropic or nonsta tionary models are in
SophisticatedModel.cc; hyper models also in Hypermodel.cc
Copyright (C) 2001 -- 2003 Martin Schlather
Copyright (C) 2004 -- 2004 Yindeng Jiang & Martin Schlather
Copyright (C) 2005 -- 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 <math.h>
#include "RF.h"
#include "Covariance.h"
//#include <R_ext/Lapack.h>
//#include <R_ext/Applic.h>
//#include <R_ext/Utils.h>
//#include <R_ext/BLAS.h>
void kdefault(cov_model *cov, int i, double v) {
cov_fct *C = CovList + cov->nr;
if (cov->p[i] == NULL) {
if (C->kappatype[i]==REALSXP) {
cov->p[i] = (double*) malloc(sizeof(double));
cov->p[i][0] = v;
} else if (C->kappatype[i]==INTSXP) {
cov->p[i] = (double*) malloc(sizeof(int));
((int *) (cov->p[i]))[0] = (int) v;
} else if (C->kappatype[i] == LISTOF + REALSXP) {
assert(false);
} else assert(false);
cov->nrow[i] = cov->ncol[i] = 1;
} else {
if (cov->nrow[i] != 1 || cov->ncol[i] != 1) {
PRINTF("%d %s %d nrow=%d, ncol=%d\n ",
cov->nr, CovList[cov->nr].name, i, cov->nrow[i], cov->ncol[i]);
int j; for (j=0; j<4; j++) PRINTF("%f\n", cov->p[i][j]);
char param_name[100];
strcpy(param_name, CovList[cov->nr].kappanames[i]);
PERR("parameter not scalar");
}
}
}
void updatepref(cov_model *cov, cov_model *sub) {
int i;
// printf("update pref %s\n", CovList[cov->nr].name);
for (i=0; i<Forbidden; i++) {
// printf("%d;%d ", cov->pref[i], sub->pref[i]);
if (sub->pref[i] < cov->pref[i]) {
cov->pref[i] = sub->pref[i];
}
}
// printf("\n");
}
void setbackward(cov_model *cov, cov_model *sub) {
// see also check_co when changing
assert(cov != NULL);
assert(sub != NULL);
if (sub->maxdim < cov->maxdim) cov->maxdim = sub->maxdim;
cov->normalmix &= sub->normalmix;
cov->finiterange &= sub->finiterange;
cov->diag &= sub->diag;
// cov->quasidiag &= sub->quasidiag;
cov->separatelast &= sub->separatelast;
cov->semiseparatelast &= sub->semiseparatelast;
if (sub->derivatives < cov->derivatives)
cov->derivatives = sub->derivatives;
updatepref(cov, sub);
cov->tbm2num |= sub->tbm2num;
cov->hess = (CovList[cov->nr].hess != NULL && sub->hess);
}
int checkkappas(cov_model *cov, bool errornull){
cov_fct *C = CovList + cov->nr;
int i,nr, nc,
kappas= C->kappas,
*ncol = cov->ncol,
*nrow = cov->nrow;
char param_name[PARAMMAXCHAR]; // used in PERR
for (i=0; i<kappas; i++) {
strcpy(param_name, C->kappanames[i]);
if (cov->p[i] == NULL) {
if (errornull) {
PERR("parameter unset");
} else continue;
}
C->kappasize(i, cov, &nr, &nc);
if (nc < 0 || nr < 0) PERR("tried to access non-existing parameters ");
if (nc == 1 && ncol[i] != nc) {
if (nr == 1 && nrow[i] != 1)
PERR("parameter must be a scalar");
PERR("parameter must be a vector, not a matrix");
}
if (nc > 1 && ncol[i] == 1)
PERR("parameter must be a matrix");
if ((nc > 0 && ncol[i] != nc) || (nr > 0 && nrow[i] != nr)) {
// nc==0, nr==0 is coded as "unknown"
char msg[255];
sprintf(msg,
"parameter not of the given size: (%d, %d) instead of (%d, %d)",
nrow[i], ncol[i], nr, nc);
PERR(msg);
}
// if nc==0 (nr==0) then this is undetermined.
}
return NOERROR;
}
int checkkappas(cov_model *cov){
return checkkappas(cov, true);
}
// $
void kappaS(int i, cov_model *cov, int *nr, int *nc){
*nc = (i==DALEFT) ? cov->xdim
: (int) (i==DVAR || i==DSCALE); // 0 mean not determined
*nr = (i == DALEFT) ? 0 :
(i == DANISO) ? cov->xdim :
i <= DMAX ? 1
: -1;
// nicht cov->tsdim !!
}
// simple transformations as variance, scale, anisotropy matrix, etc.
void Siso(double *x, cov_model *cov, double *v){
cov_model *next = cov->sub[0];
int i,
vdimSq = cov->vdim * cov->vdim;
double
var = cov->p[DVAR][0],
y = (cov->p[DANISO] == NULL ?
fabs(*x / cov->p[DSCALE][0]) : fabs(*x * cov->p[DANISO][0]));
// letzteres darf nur passieren wenn dim = 1!!
CovList[next->nr].cov(&y, next, v);
for (i=0; i<vdimSq; i++) v[i] *= var;
// printf("Siso %f %f %f\n", x[0], v[0]);
}
void Sstat(double *x, cov_model *cov, double *v){
cov_model *next = cov->sub[0];
double
**p = cov->p,
var = p[DVAR][0],
*aniso=p[DANISO];
int i,
nproj = cov->nrow[DPROJ],
vdimSq = cov->vdim * cov->vdim;
if (nproj > 0) {
int *proj = (int *)cov->p[DPROJ];
double *z = (double*) malloc(nproj * sizeof(double)),
invscale = 1.0 / p[DSCALE][0];
for (i=0; i<nproj; i++) z[i] = invscale * x[proj[i]];
CovList[next->nr].cov(z, next, v);
free(z);
} else {
if (aniso==NULL && p[DSCALE][0] == 1.0) {
CovList[next->nr].cov(x, next, v);
} else {
int xdim = cov->xdim;
double *z = (double*) malloc(xdim * sizeof(double));
if (aniso==NULL) {
double invscale = 1.0 / p[DSCALE][0];
for (i=0; i < xdim; i++) z[i] = invscale * x[i];
} else {
int j, k,
nrow=cov->nrow[DANISO],
ncol=cov->ncol[DANISO];
for (k=i=0; i<ncol; i++) {
z[i] = 0.0;
for (j=0; j<nrow; j++) {
z[i] += aniso[k++] * x[j];
}
}
}
CovList[next->nr].cov(z, next, v);
free(z);
}
}
for (i=0; i<vdimSq; i++) v[i] *= var;
}
void Snonstat(double *x, double *y, cov_model *cov, double *v){
cov_model *next = cov->sub[0];
double
**p = cov->p,
var = p[DVAR][0],
*aniso=p[DANISO];
int i,
nproj = cov->nrow[DPROJ],
vdimSq = cov->vdim * cov->vdim;
if (nproj > 0) {
int *proj = (int *)cov->p[DPROJ];
double
*z1 = (double*) malloc(nproj * sizeof(double)),
*z2 = (double*) malloc(nproj * sizeof(double)),
invscale = 1.0 / p[DSCALE][0];
for (i=0; i<nproj; i++) {
z1[i] = invscale * x[proj[i]];
z2[i] = invscale * y[proj[i]];
}
CovList[next->nr].nonstat_cov(z1, z2, next, v);
free(z1);
free(z2);
} else {
if (aniso==NULL && p[DSCALE][0] == 1.0) {
CovList[next->nr].nonstat_cov(x, y, next, v);
} else {
int xdim = cov->xdim;
double
*z1 = (double*) malloc(xdim * sizeof(double)),
*z2 = (double*) malloc(xdim * sizeof(double));
if (aniso==NULL) {
double invscale = 1.0 / p[DSCALE][0];
for (i=0; i<xdim; i++) {
z1[i] = invscale * x[i];
z2[i] = invscale * y[i];
}
} else {
int j, k,
nrow=cov->nrow[DANISO],
ncol=cov->ncol[DANISO];
for (k=i=0; i<ncol; i++) {
z1[i] = z2[i] =0.0;
for (j=0; j<nrow; j++) {
z1[i] += aniso[k] * x[j];
z2[i] += aniso[k] * y[j];
}
}
}
CovList[next->nr].nonstat_cov(z1, z2, next, v);
free(z1);
free(z2);
}
}
for (i=0; i<vdimSq; i++) v[i] *= var;
}
void DS(double *x, cov_model *cov, double *v){
cov_model *next = cov->sub[0];
int i,
vdimSq = cov->vdim * cov->vdim,
nproj = cov->nrow[DPROJ];
double y[2],
**p = cov->p,
spinvscale =
cov->p[DANISO] == NULL ? 1.0 / cov->p[DSCALE][0] : cov->p[DANISO][0],
varSc = p[DVAR][0] * spinvscale;
if (nproj == 0) {
y[0] = x[0] * spinvscale;
y[1] = (cov->isoIn==ISOTROPIC || cov->ncol[DANISO]==1) ? 0.0
: x[1] * p[DANISO][3]; // temporal; temporal scale
} else {
ERR("error in DS; please contact maintainer");
// for (i=0; i<nproj; i++) {
// y[i] = spinvscale * x[proj[i]];
}
CovList[next->nr].D(y, next, v);
for (i=0; i<vdimSq; i++) v[i] *= varSc;
}
void DDS(double *x, cov_model *cov, double *v){
cov_model *next = cov->sub[0];
int i,
vdimSq = cov->vdim * cov->vdim,
nproj = cov->nrow[DPROJ],
*proj = (int *)cov->p[DPROJ];
double y[2],
**p = cov->p,
spinvscale =
cov->p[DANISO] == NULL ? 1.0 / cov->p[DSCALE][0] : cov->p[DANISO][0],
varScSq = p[DVAR][0] * spinvscale * spinvscale;
if (nproj == 0) {
y[0] = x[0] * spinvscale;
y[1] = (cov->isoIn==ISOTROPIC || cov->ncol[DANISO]==1) ? 0.0
: x[1] * p[DANISO][3]; // temporal; temporal scale
} else {
ERR("error in DDS; please contact maintainer");
for (i=0; i<nproj; i++) {
y[0] += x[proj[i]] * x[proj[i]];
}
y[0] = sqrt(y[0]) * spinvscale;
}
CovList[next->nr].D2(y, next, v);
for (i=0; i<vdimSq; i++) v[i] *= varScSq;
}
void nablaS(double *x, cov_model *cov, double *v){
cov_model *next = cov->sub[0];
int i,
vdimSq = cov->vdim * cov->vdim,
dim = cov->nrow[DANISO],// == ncol == xdim
nproj = cov->nrow[DPROJ];
double *y,
**p = cov->p;
if (nproj != 0) ERR("error in DS; please contact maintainer");
y = (double*) malloc(sizeof(double) * dim);
if (cov->p[DANISO] == NULL) {
double spinvscale = 1.0 / cov->p[DSCALE][0],
varSc = p[DVAR][0] * spinvscale;
for (i=0; i<dim; i++) y[i] = x[i] * spinvscale;
CovList[next->nr].nabla(y, next, v);
for (i=0; i<vdimSq; i++) v[i] *= varSc;
} else {
double *z,
var = p[DVAR][0];
z = (double*) malloc(sizeof(double) * dim);
xA(x, p[DANISO], dim, dim, y);
CovList[next->nr].nabla(y, next, z);
Ax(p[DANISO], y, dim, dim, v);
for (i=0; i<dim; i++) v[i] *= var;
free(z);
}
free(y);
}
void hessS(double *x, cov_model *cov, double *v){
cov_model *next = cov->sub[0];
int i,
vdimSq = cov->vdim * cov->vdim,
nproj = cov->nrow[DPROJ],
dim=cov->nrow[DANISO],
dimsq = dim * dim; // == ncol
double *y,
**p = cov->p;
if (nproj != 0) ERR("error in DS; please contact maintainer");
y = (double*) malloc(sizeof(double) * dim);
if (cov->p[DANISO] == NULL) {
double spinvscale = 1.0 / cov->p[DSCALE][0],
varSc = p[DVAR][0] * spinvscale;
for (i=0; i<dim; i++) y[i] = x[i] * spinvscale;
CovList[next->nr].nabla(y, next, v);
for (i=0; i<vdimSq; i++) v[i] *= varSc;
} else {
double *z,
var = p[DVAR][0];
z = (double*) malloc(sizeof(double) * dimsq);
xA(x, p[DANISO], dim, dim, y);
CovList[next->nr].nabla(y, next, z);
XCXt(p[DANISO], z, v, dim, dim);
for (i=0; i<dim; i++) v[i] *= var;
free(z);
}
free(y);
}
void invS(double *x, cov_model *cov, double *v) {
cov_model *next = cov->sub[0];
int i,
vdimSq = cov->vdim * cov->vdim,
nproj = cov->nrow[DPROJ];
// *proj = (int *)cov->p[DPROJ];
double y,
**p = cov->p,
invscale =
cov->p[DANISO] == NULL ? 1.0 / cov->p[DSCALE][0] : cov->p[DANISO][0],
var = p[DVAR][0];
if (nproj == 0) {
y= *x / var; // inversion, so variance becomes scale
} else {
ERR("nproj is not allowed in invS");
}
CovList[next->nr].D(&y, next, v);
for (i=0; i<vdimSq; i++) v[i] /= invscale; //!
}
void coinitS(cov_model *cov, localinfotype *li) {
cov_model *next = cov->sub[0]->sub[0];
if ( CovList[next->nr].coinit == NULL)
error("# cannot find coinit -- please inform author");
CovList[next->nr].coinit(next, li);
}
void ieinitS(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 tbm2S(double *x, cov_model *cov, double *v){
cov_model *next = cov->sub[0];
cov_fct *C = CovList + next->nr;
double y[2],
**p=cov->p,
*aniso = p[DANISO];
assert(cov->nrow[DPROJ] == 0);
if (aniso==NULL) {
double invscale = 1.0 / p[DSCALE][0];
if (cov->xdim == 2){
y[0] = x[0] * invscale; // spatial
y[1] = x[1] * invscale; // temporal
if (y[0] == 0.0) C->cov(y, next, v);
else C->tbm2(y, next, v);
} else {
y[0] = x[0] * invscale; // purely spatial
C->tbm2(y, next, v);
}
} else {
if (cov->ncol[DANISO]==2) { // turning layers
y[0] = x[0] * aniso[0]; // spatial
y[1] = x[1] * aniso[3]; // temporal
assert(aniso[1] == 0.0 && aniso[2] == 0.0);
if (y[0] == 0.0) C->cov(y, next, v);
else C->tbm2(y, next, v);
} else {
assert(cov->ncol[DANISO]==1);
if (cov->nrow[0] == 1) { // turning bands
y[0] = x[0] * aniso[0]; // purely spatial
C->tbm2(y, next, v);
} else { // turning layers, dimension reduction
if (p[DANISO][0] == 0.0) {
y[0] = x[1] * aniso[1]; // temporal
C->cov(y, next, v);
} else {
y[0] = x[0] * aniso[0]; // temporal
C->tbm2(y, next, v);
}
}
}
}
*v *= p[DVAR][0];
}
int checkS(cov_model *cov) {
// hier kommt unerwartet ein scale == nan rein ?!!
cov_model *next = cov->sub[0];
cov_fct *C = CovList + cov->nr;
double **p = cov->p;
int i, err,
xdim = cov->xdim,
nproj = cov->nrow[DPROJ];
strcpy(ERROR_LOC, C->name);
assert(cov->nr >= DOLLAR && cov->nr<=LASTDOLLAR);
cov->nr = DOLLAR; // wegen nr++ unten !
cov->manipulating_x = !true; // !! exception as treated directly
// cov->q[1] not NULL then A has been given
if (cov->q == NULL && cov->p[DALEFT]!=NULL) {
// here for the first time
if (p[DANISO] != NULL) ERR("aniso and A may not be given at the same time");
int j, k,
nrow = cov->nrow[DALEFT],
ncol = cov->ncol[DALEFT],
total = ncol * nrow;
double
*pA = p[DALEFT];
p[DANISO] = (double*) malloc(sizeof(double) * total);
cov->nrow[DANISO] = ncol;
cov->ncol[DANISO] = nrow;
for (i=k=0; i<nrow; i++) {
for (j=i; j<total; j+=nrow) p[DANISO][k++] = pA[j];
}
cov->q = (double*) calloc(1, sizeof(double));
cov->qlen = 1;
}
kdefault(cov, DVAR, 1.0);
if (p[DANISO] != NULL) { // aniso given
int *idx=NULL,
nrow = cov->nrow[DANISO],
ncol = cov->ncol[DANISO];
bool quasidiag;
matrix_type type;
idx = (int *) malloc((nrow > ncol ? nrow : ncol) * sizeof(int));
if (nrow==0 || ncol==0) ERR("no dimension of the matrix may be 0");
if (nproj > 0 || cov->ncol[DPROJ] > 0)
ERR("the parameters aniso and proj may not be given at the same time");
analyse_matrix(p[DANISO], nrow, ncol,
&(cov->diag),
&quasidiag, // &(cov->quasidiag),
idx, // cov->idx
&(cov->semiseparatelast),
&(cov->separatelast));
free(idx); idx=NULL;
type = Type(p[DANISO], nrow, ncol);
cov->derivatives = (cov->xdim == 1 || nrow == ncol) ? 2 : 0;
if (xdim < nrow) {
// || ( xdim > nrow &&
// (cov->tsdim != nrow || type!=TypeIso || xdim != 1)))
if (PL > 6) PRINTF("xdim=%d != nrow=%d\n", xdim, nrow);
strcpy(ERRORSTRING,
"#rows of anisotropy matrix does not match dim. of coordinates");
return ERRORM;
}
if (cov->isoIn == SPACEISOTROPIC) {
cov->derivatives = 2;
if (type != TypeDiag && type != TypeIso) {
strcpy(ERRORSTRING, "spaceisotropic needs diagonal matrix");
return ERRORM + 1;
}
}
if (p[DSCALE] != NULL) {
strcpy(ERRORSTRING,
"aniso and scale may not be given at the same time");
return ERRORM + 2;
}
if (p[DPROJ] != NULL) {
strcpy(ERRORSTRING,
"aniso and proj may not be given at the same time");
return ERRORM + 2;
}
if (cov->xdim != cov->tsdim && nrow != ncol) {
strcpy(ERRORSTRING, "non-quadratic anisotropy matrices only allowed if dimension of coordinates equals spatio-temporal dimension");
return ERRORM + 3;
}
if (!cov->diag)
cov->pref[RandomCoin] = cov->pref[Hyperplane]=0;//=cov->pref[SpectralTBM]
if ((err = check2X(next, ncol, ncol, cov->statIn,
ncol==1 ? ISOTROPIC : cov->isoIn,
SUBMODELM))
!= NOERROR) return err;
if (next->sub[0]->statIn == cov->statIn &&
next->sub[0]->isoIn == cov->isoIn &&
cov->xdim > 1)
next->tsdim = DEL_COV - 7;
// kdefault(cov, DSCALE, 1.0);
} else { // aniso == NULL
// int xdim2 = xdim * xdim,
// step = xdim + 1;
// if (cov->q[1] < 0.0 && (cov->tsdim != xdim || nproj > 0)) {
// strcpy(ERRORSTRING, "aniso cannot be forced");
/// return ERRORM + 4;
// }
int tsdim = cov->tsdim;
if (nproj > 0) {
bool *used = (bool*) malloc(xdim * sizeof(bool));
if (cov->ncol[DPROJ] != 1) ERR("proj must be a vector");
for (i=0; i<xdim; i++) used[i] = false;
for (i=0; i<xdim; i++) {
int idx = ((int *) cov->p[DPROJ])[0];
if (used[idx] ) ERR("components in proj are given twice");
used[idx] = true;
}
xdim = nproj;
tsdim = nproj;
free(used);
}
kdefault(cov, DSCALE, 1.0);
// if (p[DANISO] != NULL) free(p[DANISO]);
// p[DANISO] = NULL;
/*
p[DANISO] = (double*) calloc(xdim2, sizeof(double));
ncol = nrow = cov->ncol[DANISO] = cov->nrow[DANISO] = xdim;
double ani = 1.0 / p[DSCALE][0];
for (i=0; i<xdim2; i+=step) p[DANISO][i] = ani;
*/
if ((err = check2X(next, tsdim, 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 - 8;
}
// if ((p[DANISO] != NULL && p[DANISO][0] >= 0 && xdim==1) next->tsdim = DEL_COV;
cov->vdim = next->vdim;
setbackward(cov, next);
err = checkkappas(cov, false); // !! unchecked on NULL !!
if (cov->p[DANISO] != NULL) {
cov->pref[Nugget] = cov->pref[TBM3] = cov->pref[TBM2] = 0;
}
if (err != NOERROR) return err;
if (cov->xdim > 1) {
cov->pref[CircEmbedCutoff] = cov->pref[CircEmbedIntrinsic] = 0;
cov->nr++;
}
cov->pref[CircEmbedCutoff] = cov->pref[CircEmbedIntrinsic] =
cov->pref[TBM3] = cov->pref[TBM2] = cov->pref[SpectralTBM] = 0;
return NOERROR;
}
int initspectralS(cov_model *cov) {
cov_model *next = cov->sub[0];
// printf("$ ------> %s %d\n", CovList[next->nr].name, 5);
if (CovList[next->nr].initspectral == NULL) return ERRORFAILED;
memcpy(&(next->spec), &(cov->spec), sizeof(spec_covstorage));
int err=CovList[next->nr].initspectral(next);
memcpy(&(cov->spec), &(next->spec), sizeof(spec_covstorage));
// printf("$ ------> %s %d\n", CovList[next->nr].name, err);
return err;
}
void spectralS(cov_model *cov, spectral_storage *s, double *e) {
int d;
cov_model *next = cov->sub[0];
double *sube;
if (cov->p[DSCALE] != NULL) {
int dim = cov->tsdim;
double
invscale = 1.0 / cov->p[DSCALE][0];
sube = (double*) malloc(dim * sizeof(double));
CovList[next->nr].spectral(next, s, sube);
for (d=0; d<dim; d++) e[d] = sube[d] * invscale;
} else {
int j, k,
nrow = cov->xdim,
ncol = next->xdim;
double
*A = cov->p[DANISO];
sube = (double*) malloc(ncol * sizeof(double));
CovList[next->nr].spectral(next, s, sube);
for (d=0, k=0; d<nrow; d++, k+=nrow) {
e[d] = 0.0;
for (j=0; j<ncol; j++) {
e[d] += sube[j] * A[j + k];
}
}
}
free(sube);
}
void rangeS(cov_model *cov, range_arraytype* ra){
range_type *range = ra->ranges + 0;
int i;
range->finiterange = true;
range->maxdim = INFDIM;
range->min[DVAR] = 0.0;
range->max[DVAR] = RF_INF;
range->pmin[DVAR] = 0.0;
range->pmax[DVAR] = 100000;
range->openmin[DVAR] = false;
range->openmax[DVAR] = true;
range->min[DSCALE] = 0.0;
range->max[DSCALE] = RF_INF;
range->pmin[DSCALE] = 0.0001;
range->pmax[DSCALE] = 10000;
range->openmin[DSCALE] = true;
range->openmax[DSCALE] = false;
for (i=DANISO; i<= DALEFT; i++) {
range->min[i] = RF_NEGINF;
range->max[i] = RF_INF;
range->pmin[i] = -10000;
range->pmax[i] = 10000;
range->openmin[i] = true;
range->openmax[i] = true;
}
}
int initS(method_type *meth){
// am liebsten wuerde ich hier die Koordinaten transformieren;
// zu grosser Nachteil ist dass GetDiameter nach trafo
// grid def nicht mehr ausnutzen kann -- umgehbar?!
cov_model *cov=meth->cov;
globalparam *gp = meth->gp;
int err,
PL = gp->general.printlevel;
// ncol = cov->ncol[DANISO],
// nrow = cov->nrow[DANISO];
if (meth->hanging != NULL) {
if (PL>4) PRINTF("hanging %d\n", meth->hanging->nr);
if (meth->hanging->nr != ISO2ISO &&
meth->hanging->nr != SP2SP &&
meth->hanging->nr != S2S
) {
if (PL>5) {
PRINTF("initS:\n");
PrintMethodInfo(meth); //
}
return ERRORHANGING;
}
}
// 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);
sub->cvar *= cov->p[DVAR][0];
// int nproj = cov->nrow[DPROJ],
// mnrow = meth->loc->timespacedim,
// mncol = nrow;
// matrix_type type_method;
cum_dollar(meth, meth->loc->timespacedim, cov, sub);
sub->cov = cov->sub[0];
// PrintMethodInfo(sub); assert(false);
err = initstandard(sub);
meth->compatible = sub->compatible && (sub->cvar == 1.0);
meth->domethod = doS;
meth->S = NULL;
meth->nr = DOLLAR;
return err;
}
void doS(method_type *meth, res_type *res){
int i,
m=0,
totalpoints = meth->loc->totalpoints;
double sd = sqrt(meth->sub[m]->cvar);
do_meth dometh = meth->sub[m]->domethod;
// printf("doS %f %f %s\n", res[0], sd, CovList[meth->cov->nr].name);
dometh(meth->sub[m], res);
// printf("doS emitte %f\n", res[0]);
if (sd != 1.0) {
for (i=0; i<totalpoints; i++) {
res[i] *= (res_type) sd;
}
}
// printf("doS end%f\n", res[0]);
}
/* simplifying functions
turn vector of x into length ||x|| and similar
reduces C(x,y) to C(x - y)
needs preceeding analysis of submodels!
(same for preferred methods; bottom-up-analysis needed)
*/
// #
// keep always the orderung
void iso2iso(double *x, cov_model *cov, double *v) {
cov_model *next = cov->sub[0];
double y=fabs(*x);
CovList[next->nr].cov(&y, next, v);
}
void spiso2spiso(double *x, cov_model *cov, double *v) {
cov_model *next = cov->sub[0];
double y[2];
y[0] = fabs(x[0]);
y[1] = fabs(x[1]);
CovList[next->nr].cov(y, next, v);
}
void spacetime2iso(double *x, cov_model *cov, double *v) {
cov_model *next = cov->sub[0];
double y=sqrt(x[0] * x[0] + x[1] * x[1]);
CovList[next->nr].cov(&y, next, v);
}
void Stat2iso(double *x, cov_model *cov, double *v) {
cov_model *next = cov->sub[0];
double b = 0.0;
int i,
dim=cov->xdim;
// printf("dim=%d, %d\n", dim, x[0]);
for (i=0; i<dim; i++) {
b += x[i] *x[i];
}
b = sqrt(b);
CovList[next->nr].cov(&b, next, v);
}
void Nonstat2iso(double *x, double *y, cov_model *cov, double *v) {
cov_model *next = cov->sub[0];
double a, b;
int dim=cov->xdim, i;
for (b=0.0, i=0; i<dim; i++) {
a = y[i] - x[i];
b += a * a;
}
b = sqrt(b);
CovList[next->nr].cov(&b, next, v);
}
void Stat2spacetime(double *x, cov_model *cov, double *v) {
cov_model *next = cov->sub[0];
double b, z[2];
int i,
dim=cov->xdim - 1;
for (b=0.0, i=0; i<dim; i++) b += x[i] * x[i];
z[0] = sqrt(b);
z[1] = fabs(x[dim]);
CovList[next->nr].cov(z, next, v);
}
void Nonstat2spacetime(double *x, double *y, cov_model *cov, double *v) {
//assert(false);
cov_model *next = cov->sub[0];
double a, b, z[2];
int dim=cov->xdim - 1, i;
for (b=0.0, i=0; i<dim; i++) {
a = y[i] - x[i];
b += a * a;
}
z[0] = sqrt(b);
z[1] = fabs(y[dim] - x[dim]);
CovList[next->nr].cov(z, next, v);
}
void Stat2Stat(double *x, cov_model *cov, double *v) {
cov_model *next = cov->sub[0];
CovList[next->nr].cov(x, next, v);
}
void Nonstat2Stat(double *x, double *y, cov_model *cov, double *v) {
cov_model *next = cov->sub[0];
int i,
dim=cov->xdim;
double *z = (double*) malloc(dim * sizeof(double));
for (i=0; i<dim; i++) z[i] = y[i] - x[i];
CovList[next->nr].cov(z, next, v);
free(z);
}
void D_2(double *x, cov_model *cov, double *v){
cov_model *next = cov->sub[0];
if (cov->isoIn == ISOTROPIC) {
double y = fabs(*x);
PrintModelInfo(cov->calling->calling->calling); // ok
PrintModelInfo(cov); // ok
// iso2iso ueberpruefen !!!
// dollar + scale // aniso > 0 und dim = 1
// nach tbm eigentlich auch nicht
// cov->sub[1000] = cov->sub[1];
assert(false); // sollte nicht auftreten !!
CovList[next->nr].D(&y, next, v);
} else {
assert(cov->isoIn == SPACEISOTROPIC);
cov_model *next = cov->sub[0];
cov_fct *N = CovList + next->nr;
if (N->isotropy==ISOTROPIC) {
assert(next->xdim == 1);
double y=sqrt(x[0] * x[0] + x[1] * x[1]);
N->D(&y, next, v);
if (y!=0.0) *v = x[0] / y;
} else {
assert(N->isotropy == SPACEISOTROPIC);
double y[2];
y[0] = fabs(x[0]);
y[1] = fabs(x[1]);
N->D(y, next, v);
}
}
}
void DD_2(double *x, cov_model *cov, double *v) {
cov_model *next = cov->sub[0];
if (cov->isoIn == ISOTROPIC) {
double y = fabs(*x);
PrintModelInfo(cov->calling->calling->calling); // ok
// iso2iso ueberpruefen !!!
// dollar + scale // aniso > 0 und dim = 1
// nach tbm eigentlich auch nicht
assert(false); // sollte nicht auftreten !!
CovList[next->nr].D2(&y, next, v);
} else {
assert(cov->isoIn == SPACEISOTROPIC);
cov_model *next = cov->sub[0];
cov_fct *N = CovList + next->nr;
if (N->isotropy==ISOTROPIC) {
assert(next->xdim == 1);
double w,
xSq = x[0] * x[0],
tSq = x[1] * x[1],
ySq = xSq + tSq,
y = sqrt(ySq);
// (c'(r) * x/r)' = c''(r) * x^2/r^2 + c'(r) [ 1/r - x^2 / r^3]
N->D2(&y, next, v);
if (y != 0.0) {
N->D(&y, next, &w);
w /= y;
*v = (*v - w) * xSq / ySq + w;
}
else {
*v = x[0] / y;
}
} else {
assert(N->isotropy == SPACEISOTROPIC);
double y[2];
y[0] = fabs(x[0]);
y[1] = fabs(x[1]);
N->D2(y, next, v);
}
}
}
void inv2(double *x, cov_model *cov, double *v) {
cov_model *next = cov->sub[0];
double y=fabs(*x);
CovList[next->nr].invSq(&y, next, v);
}
// void hyper2
void setdefault(cov_model *cov) {
// Achilles-Ferse: setdefault wird aufgerufen bevor die Varianten
// der Modelle und Operatoren feststehen -- die Parameter unten muessen, falls
// notwendig von Hand in den checks gesetzt werden.
// cov_model *prev=cov->calling;
int i;
cov_fct *C = CovList + cov->nr;
cov->maxdim = INFDIM;
cov->normalmix =
cov->finiterange =
cov->diag =
// cov->quasidiag =
cov->semiseparatelast =
cov->separatelast = true;
// cov->variogram = false;
// for(i=0; i<cov->xdim; i++) cov->idx[i] = i;
// int in=1, op=1;
// PrintModelList(&in, &op);
memcpy(cov->pref, C->pref, sizeof(pref_shorttype));
for (i=Nothing+1; i<Forbidden; i++) cov->pref[i] = PREF_NONE;
for (i=0; i<Forbidden; i++) {
// printf("%s %s %d\n", C->name, METHODNAMES[i], C->pref[i]);
if (cov->user[i] < cov->pref[i])
cov->pref[i] = cov->user[i];
}
// if (prev != NULL) {
// cov->tsdim = prev->tsdim;
// cov->xdim = prev->xdim;
// }
cov->tbm2num = C->implemented[TBM2] == NUM_APPROX;
if (C->isotropy == ISOTROPIC) {
cov->xdim = 1;
} else if (C->isotropy == SPACEISOTROPIC) {
cov->xdim = 2;
}
}
int check2intern(cov_model *cov){
bool ANI = false; // GLOBAL.general.aniso;
cov_model *next = cov->sub[0];
cov_fct *C = CovList + cov->nr,
*N = CovList + next->nr;
isotropy_type iso, first_iso, last_iso, iso0;
stationary_type stat, first_stat, last_stat;
int i, err;
bool skipchecks = GLOBAL.general.skipchecks;
// printf(">>> %s \n", N->name);
if (cov->xdim < 1) ERR("dimension less than 1");
if (PL > 7) PRINTF("checking %s ~ %s\n", C->name, CovList[next->nr].name);
if (next->nr == GATTER) {
PRINTF("------------\n");
PrintModelInfo(cov); // ok
PRINTF("------------\n");
assert(false);
}
setdefault(cov);
next->tsdim = cov->tsdim;
first_iso = last_iso = next->isoIn = N->isotropy;
first_stat = last_stat = next->statIn = N->stationary;
// erst by check unten
strcpy(ERROR_LOC, CovList[next->nr].name);
if (PL > 8) PRINTF("%s\n", ERROR_LOC);
next->xdim = cov->xdim; // if next is isotropy or spaceisotropic it is
// set to 1 or 2
setdefault(next);
// if (CovList[next->nr].primitive) {//29.12.09 geloescht; jetzt in simu.cc l416
// RUECKGEANDERT 15.1.11 -- darf auf keinen Fall in simu.cc, da sonst der
// Aufbau gestoert wird!!
if (CovList[next->nr].primitive &&
(err = checkkappas(next)) != NOERROR) return err;
sprintf(ERROR_LOC, "the starting point to `%s'", CovList[next->nr].name);
if (PL > 8) PRINTF("%s\n", ERROR_LOC);
// printf("check2intern %s %d %d; %s %d %d\n",
// CovList[cov->nr].name, cov->statIn, cov->isoIn,
// N->name, N->stationary, N->isotropy);
if (first_iso == PREVMODELI) {
first_iso = ISOTROPIC;
last_iso = ANISOTROPIC;
}
if (last_iso > cov->isoIn) last_iso = cov->isoIn;
if (last_iso < first_iso) {
sprintf(ERRORSTRING,
"cannot call non-isotropic model from isotropic one (%s -> %s)",
ISONAMES[(int) cov->isoIn], ISONAMES[(int) next->isoIn]);
return ERRORM;
}
if (first_stat == PREVMODELS) {
first_stat = STATIONARY;
last_stat = GENERALISEDCOVARIANCE;
}
if (last_stat > cov->statIn) last_stat = cov->statIn;
if (last_stat < first_stat) {
// PRINTF("code %d %d\n", prev->stationary, cov->stationary);
sprintf(ERRORSTRING,
"cannot call more complex model from less complex one (%s -> %s)",
STATNAMES[(int) cov->statIn], STATNAMES[(int) next->statIn]);
return ERRORM + 1;
}
err = ERRORNOSTATMATCH;
next->tsdim = cov->tsdim;
strcpy(ERROR_LOC, CovList[next->nr].name);
if (PL > 4)
PRINTF("%s (stat.start=%d, end=%d)\n", ERROR_LOC, first_stat, last_stat);
for (stat = first_stat; stat <= last_stat; stat++) {
next->statIn = stat;
for (iso0=first_iso; iso0 <= last_iso; iso0++) {
// printf("GEEE %d %d %d iso %d %d %d\n",
// stat, first_stat, last_stat, iso0, first_iso, last_iso);
iso = iso0;
if (ANI && last_iso >= ANISOTROPIC && first_iso <= SPACEISOTROPIC) {
// bei mpp darf keine Reduktion stattfinden !
if (iso == ANISOTROPIC) iso = SPACEISOTROPIC;
else if (iso == SPACEISOTROPIC) iso = ANISOTROPIC;
}
next->derivatives = N->derivs;
// printf("xxx GEEE dsaf %d %d %s %s\n", cov->xdim, N->derivs, N->name,
// CovList[next->nr].name);
if (cov->xdim == 1) {
if ((iso == SPACEISOTROPIC) || (iso == ZEROSPACEISO) ||
(iso != ISOTROPIC && (stat == STATIONARY || stat == VARIOGRAM ||
stat == IRF) &&
cov->vdim<2 && cov->vdim != SUBMODELM)
) continue;
}
next->xdim =
iso == ISOTROPIC ? 1 : iso == SPACEISOTROPIC ? 2 : cov->xdim;
next->isoIn = iso;
next->vdim = N->vdim;
// printf("zz GEEE dsaf %d %d %d %s %s\n",
// cov->xdim, N->derivs, next->derivatives, N->name,
// CovList[next->nr].name);
// printf("%s GEEE dsaf %d\n", CovList[next->nr].name, err);
if ((err = CovList[next->nr].check(next)) == NOERROR) break;
// printf("%s GEEd sd E\n", CovList[next->nr].name);
}
if (err == NOERROR) break;
}
if (err != NOERROR) return err;
if (next->vdim <= 0) {
// PrintModelInfo(cov); // Ok
ERR("something is wrong with the m-dimensionality");
}
cov->vdim = next->vdim;
// printf("bback\n");
// PrintModelInfo(cov);
sprintf(ERROR_LOC, "Back from `%s':", CovList[next->nr].name);
if (PL > 8) PRINTF("%s\n", ERROR_LOC);
if (!skipchecks && (err = check_within_range(next, NAOK_RANGE)) != NOERROR) {
return err;
}
if (CovList[next->nr].primitive) {
/* range check of submodel if Primitive !! */
for (i=0; i<Forbidden; i++) {
if (next->user[i] < next->pref[i])
next->pref[i] = next->user[i];
}
}
cov->derivatives = (cov->statIn == STATIONARY || cov->statIn == VARIOGRAM) &&
((cov->isoIn == ISOTROPIC) ||
(cov->isoIn == SPACEISOTROPIC && next->isoIn ==SPACEISOTROPIC)) ? 2 : 0;
// printf("yy GEEE dsaf xdim=%d der=%d n=%d %s; %s %d\n",
// cov->xdim, CovList[next->nr].derivs, next->derivatives, N->name,
// CovList[cov->nr].name, cov->derivatives);
setbackward(cov, next);
return NOERROR;
}
int check2(cov_model *cov) {
cov_model *next = cov->sub[0];
int err = ERRORNOSTATMATCH;
stationary_type stat, first, last;
cov->manipulating_x = !true; // exception as treated directly
if (cov->statIn == STATIONARY) {
first = STATIONARY;
last = IRF;
/////////////
// last = STATIONARY;
} else {
first = COVARIANCE;
last = GEN_VARIOGRAM;
}
cov->vdim = SUBMODELM;
cov->isoIn = ANISOTROPIC;
for (stat=first; stat <= last; stat++) {
// printf("%s%s %s [%s %s]\n", CovList[cov->nr].name,
// CovList[cov->sub[0]->nr].name,
// STATNAMES[(int) stat], STATNAMES[(int) first],
// STATNAMES[(int) last]);
cov->statIn = stat;
if ((err = check2intern(cov)) == NOERROR) break;
// printf("intern GEEE dsaf %d \n", err);
if (PL > 1) {
PRINTF("error when assuming `%s':\n", STATNAMES[(int) stat]);
ErrorMessage(Nothing, err);
}
}
if (err != NOERROR) return err;
cov->statIn = next->statIn;
if (next->statIn == STATIONARY || next->statIn == GENERALISEDCOVARIANCE ||
next->statIn == VARIOGRAM ||
next->statIn == IRF) {
switch(next->isoIn) {
case ISOTROPIC :
cov->nr = S2ISO; // auch bei xdim == 1, da hier
// nicht S2ISO sondern NonStat2Iso gemeint ist!
break;
case SPACEISOTROPIC :
cov->nr = S2SP;
break;
case ZEROSPACEISO: case ANISOTROPIC :
cov->nr = S2S;
break;
default : assert(false);
}
} else {
if (next->statIn == AUXMATRIX || next->statIn == AUXVECTOR)
ERR("auxiliary functions are not allowed on top level");
if (next->statIn != COVARIANCE && next->statIn != GEN_VARIOGRAM)
ERR("the translation invariance property of the model is unknown");
cov->tsdim = DEL_COV - 1;
}
return NOERROR;
}
int check2X(cov_model *cov, int tsdim, int xdim,
stationary_type statprev, isotropy_type isoprev,
int vdim
) {
cov_model *next = cov->sub[0],
*prev = cov->calling;
int err;
// long double sss;
// PrintModelInfo(cov);
// printf("%d %d\n", sizeof(long double), sizeof(double)); assert(false);
assert(prev != NULL);
assert(cov->nr >= GATTER && cov->nr <= LASTGATTER);
cov->isoIn = isoprev;
cov->statIn = statprev;
cov->xdim = xdim;
cov->tsdim = tsdim;
cov->vdim = vdim; // e.g. nugget is adapted to required vdim
// assert(xdim > 1 || // deleted 28.12.08 da Aufrufe von ANISO models mit xdim=1fehlerhaft
// isoprev == ISOTROPIC || vdim > 1 ||
// statprev != STATIONARY && statprev != VARIOGRAM && statprev != IRF);
sprintf(ERROR_LOC, "#[%s -> %s] (%d %d)",
CovList[prev->nr].name, CovList[next->nr].name, statprev, isoprev);
if (PL > 4) PRINTF("%s\n", ERROR_LOC);
if ((err = check2intern(cov)) != NOERROR) {
// printf("2X err=%d\n", err);
return err;
}
if (vdim > 0) {
if (vdim != cov->vdim) ERR("the m-dimensionality does not match");
} else if (vdim != SUBMODELM)
ERR("preceding model has unexpected m-dimensionality")
// printf("Xhere\n");
if (next->statIn == AUXMATRIX || next->statIn == AUXVECTOR) {
cov->tsdim = DEL_COV - 2;
return NOERROR;
}
if (isoprev == SPACEISOTROPIC) {
assert(cov->xdim == 2);
cov->pref[TBM2] = 0;
}
if (statprev < next->statIn)
ERR("cannot call more complex models from simpler ones");
if (statprev == GENERALISEDCOVARIANCE &&
(next->statIn != GENERALISEDCOVARIANCE && next->statIn != STATIONARY))
ERR("translation invariance does not match with generalised covariance");
switch(statprev) {
case STATIONARY : case VARIOGRAM : case IRF : case AUXMATRIX :
case GENERALISEDCOVARIANCE :
switch(isoprev) {
case ISOTROPIC :
cov->nr = ISO2ISO; // iso2iso
break;
case SPACEISOTROPIC :
cov->nr = (next->isoIn == ISOTROPIC) ? SP2ISO : SP2SP;
break;
case ZEROSPACEISO: case ANISOTROPIC :
switch (next->isoIn) {
case ISOTROPIC :
cov->nr = S2ISO;
// if (prev->quasidiag)
// for (i=0; i<xdim; i++) prev->idx[i] = i;
break;
case SPACEISOTROPIC :
cov->nr = S2SP;
// if (cov->quasidiag) {
// if ((cov->diag = cov->quasidiag = next->idx[1] ==1))
// { for (i=0; i<xdim; i++) prev->idx[i] = i; }
break;
case ZEROSPACEISO: case ANISOTROPIC :
cov->tsdim = DEL_COV - 5;
break;
default : assert(false);
}
break;
default:
PRINTF("%s %d %d\n", CovList[next->nr].name, statprev, isoprev);
assert(false);
}
break;
case AUXVECTOR :
if (next->statIn != AUXVECTOR) return ERRORAUXVECTOR;
break;
case COVARIANCE : case GEN_VARIOGRAM :
if (next->statIn == STATIONARY || next->statIn == VARIOGRAM ||
next->statIn == IRF || next->statIn==AUXMATRIX){
switch(next->isoIn) {
case ISOTROPIC :
cov->nr = S2ISO;
// if (prev->quasidiag)
// for (i=0; i<xdim; i++) prev->idx[i] = i;
break;
case SPACEISOTROPIC :
cov->nr = S2SP;
// if (prev->quasidiag) {
// if ((prev->diag = prev->quasidiag = cov->idx[1] == 1)) {
// for (i=0; i<xdim; i++) prev->idx[i] = i;
// }
//}
break;
case ZEROSPACEISO: case ANISOTROPIC :
cov->nr = S2S;
//if (prev->quasidiag)
// for (i=0; i<xdim; i++) prev->idx[i] = cov->idx[i];
break;
default: assert(false);
}
} else { // still non-stationary: cannot be simplified
cov->tsdim = DEL_COV - 4;
}
break;
default :
PrintModelInfo(cov); // ok
PRINTF("%d %s\n", prev->statIn, CovList[prev->nr].name);
assert(false);
}
return NOERROR;
}
void range2(cov_model *cov, range_arraytype* ra){
range_type *range = ra->ranges;
range->finiterange = true;
range->maxdim = INFDIM;
}
int init2(method_type *meth){
int err;
cov_model *newcov=NULL,
*cov = meth->cov,
*next = cov->sub[0];
meth->hanging = meth->cov;
if (CovList[next->nr].initmethod == NULL)
return ERRORSUBMETHODFAILED;
covcpy(&newcov, next, true, true);
assert(newcov->nr >= GATTER && newcov->nr<=LASTGATTER);
removeOnly(&newcov);
setdefault(newcov);
newcov->statIn = cov->statIn;
newcov->isoIn = cov->isoIn;
newcov->xdim = cov->xdim;
// PrintModelInfo(newcov); assert(false);
if ((err = CovList[newcov->nr].check(newcov)) != NOERROR) {
COV_DELETE(&newcov);
XERR(err);
}
DeleteGatter(&newcov);
//
// PrintModelInfo(newcov);assert(false);
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);
sub->cov = newcov;
// PrintMethodInfo(meth);
if (meth->gp->general.printlevel >= 5) {
// PRINTF(" trying initialisation of model `%s' [%d; %ld].\n",
// CovList[next->nr].name, next->nr,
// (POINTER) CovList[next->nr].initmethod);
}
if ((err = CovList[next->nr].initmethod(sub)) != NOERROR) {
return err;
}
meth->compatible = sub->compatible;
meth->domethod = do2;
meth->S = NULL;
meth->nr = GATTER;
return NOERROR;
}
void do2(method_type *meth, res_type *res){
meth->sub[0]->domethod(meth->sub[0], res);
}
int initspectral2(cov_model *cov) {
cov_model *next = cov->sub[0];
// printf("initsp2 %ld %s\n",
// CovList[next->nr].initspectral, CovList[next->nr].name);
// assert(CovList[next->nr].initspectral != NULL);
if (CovList[next->nr].initspectral == NULL) {
return ERRORFAILED;
}
// printf("sp err gatter null %s %d\n", CovList[next->nr].name, CovList[next->nr].initspectral(next));
memcpy(&(next->spec), &(cov->spec), sizeof(spec_covstorage));
int err=CovList[next->nr].initspectral(next);
memcpy(&(cov->spec), &(next->spec), sizeof(spec_covstorage));
return err;
}
void spectral2(cov_model *cov, spectral_storage *s, double *e) {
cov_model *next = cov->sub[0];
return CovList[next->nr].spectral(next, s, e);
}
void mppinit2(mpp_storage *s, cov_model *cov) {
cov_model *next = cov->sub[0];
CovList[next->nr].mppinit(s, next);
}
void coin2(mpp_storage *s, cov_model *cov){
cov_model *next = cov->sub[0];
CovList[next->nr].randomcoin(s, next);
}
void sd2(mpp_storage *s, cov_model *cov) {
cov_model *next = cov->sub[0];
CovList[next->nr].sd(s, next);
}
res_type mppgetiso2iso(double *x, cov_model *cov, mpp_storage *s) {
cov_model *next = cov->sub[0];
double y=fabs(*x);
return CovList[next->nr].mppgetstat(&y, next, s);
}
res_type mppgetspiso2spiso(double *x, cov_model *cov, mpp_storage *s) {
cov_model *next = cov->sub[0];
double y[2];
y[0] = fabs(x[0]);
y[1] = fabs(x[1]);
return CovList[next->nr].mppgetstat(y, next, s);
}
res_type mppgetspacetime2iso(double *x, cov_model *cov, mpp_storage *s) {
cov_model *next = cov->sub[0];
double y=sqrt(x[0] * x[0] + x[1] * x[1]);
return CovList[next->nr].mppgetstat(&y, next, s);
}
res_type mppgetStat2iso(double *x, cov_model *cov, mpp_storage *s) {
cov_model *next = cov->sub[0];
double b = 0.0;
int i,
dim=cov->xdim;
for (i=0; i<dim; i++) {
b += x[i] *x[i];
}
b = sqrt(b);
return CovList[next->nr].mppgetstat(&b, next, s);
}
res_type mppgetNonstat2iso(double *x, double *y, cov_model *cov, mpp_storage *s) {
cov_model *next = cov->sub[0];
double a, b;
int dim=cov->xdim, i;
// PrintModelInfo(cov); assert(false);
for (b=0.0, i=0; i<dim; i++) {
a = y[i] - x[i];
b += a * a;
}
b = sqrt(b);
return CovList[next->nr].mppgetstat(&b, next, s);
}
res_type mppgetStat2spacetime(double *x, cov_model *cov, mpp_storage *s) {
cov_model *next = cov->sub[0];
double b, z[2];
int i,
dim=cov->xdim - 1;
for (b=0.0, i=0; i<dim; i++) b += x[i] * x[i];
z[0] = sqrt(b);
z[1] = fabs(x[dim]);
return CovList[next->nr].mppgetstat(z, next, s);
}
res_type mppgetNonstat2spacetime(double *x, double *y, cov_model *cov,
mpp_storage *s) {
//assert(false);
cov_model *next = cov->sub[0];
double a, b, z[2];
int dim=cov->xdim - 1, i;
for (b=0.0, i=0; i<dim; i++) {
a = y[i] - x[i];
b += a * a;
}
z[0] = sqrt(b);
z[1] = fabs(y[dim] - x[dim]);
return CovList[next->nr].mppgetstat(z, next, s);
}
res_type mppgetStat2Stat(double *x, cov_model *cov, mpp_storage *s) {
cov_model *next = cov->sub[0];
return CovList[next->nr].mppgetstat(x, next, s);
}
res_type mppgetNonstat2Stat(double *x, double *y, cov_model *cov, mpp_storage *s) {
cov_model *next = cov->sub[0];
int i,
dim=cov->xdim;
double *z = (double*) malloc(dim * sizeof(double));
for (i=0; i<dim; i++) z[i] = y[i] - x[i];
return CovList[next->nr].mppgetstat(z, next, s);
free(z);
}
cov_model *covOhneGatter(cov_model *cov) {
return (cov->nr >= GATTER && cov->nr <= LASTGATTER) ? cov->sub[0] : cov;
}
int checkplusmal(cov_model *cov) {
cov_model *sub;
int i, err; // taken[MAX DIM],
cov->manipulating_x = X_PASSED;
for (i=0; i<cov->nsub; i++) {
sub=cov->sub[i];
if (sub == NULL)
ERR("+ or *: named submodels are not given in a sequence!");
if ((err = check2X(sub, cov->tsdim, cov->xdim, cov->statIn, cov->isoIn,
SUBMODELM)) != NOERROR) {
// printf("error\n");
return err;
}
if (i==0) cov->vdim=sub->vdim;
else if (cov->vdim != sub->vdim)
ERR("m-dimensionality must be equal in the submodels ");
setbackward(cov, sub);//cov->sub[i] may now point to somewhere else!
if (sub->sub[0]->statIn == cov->statIn &&
sub->sub[0]->isoIn == cov->isoIn) {
sub->tsdim = DEL_COV - 6;
} else {
if (sub->statIn != cov->statIn || sub->isoIn != cov->isoIn)
return ERRORFAILED;
}
}
// !! incorrect !!
cov->semiseparatelast = false; // taken[xdim - 1] <= 1;
cov->separatelast = false; // taken[xdim - 1] <= 1; ??
return NOERROR;
}
void plusStat(double *x, cov_model *cov, double *v){
cov_model *sub;
int i, m,
nsub=cov->nsub,
vsq = cov->vdim * cov->vdim;
double *z = (double*) malloc(sizeof(double) * vsq);
assert(x[0] >= 0.0 || cov->xdim > 1);
for (m=0; m<vsq; m++) v[m] = 0.0;
for(i=0; i<nsub; i++) {
sub = cov->sub[i];
CovList[sub->nr].cov(x, sub, z);
// printf("(%s %f %f) ", CovList[sub->sub[0]->nr].name, *x, *z);
for (m=0; m<vsq; m++) v[m] += z[m];
}
free(z);
}
void plusNonStat(double *x, double *y, cov_model *cov, double *v){
cov_model *sub;
int i, m,
nsub=cov->nsub,
vsq = cov->vdim * cov->vdim;
double *z = (double*) malloc(sizeof(double) * vsq);
for (m=0; m<vsq; m++) v[m] = 0.0;
for(i=0; i<nsub; i++) {
sub = cov->sub[i];
CovList[sub->nr].nonstat_cov(x, y, sub, z);
for (m=0; m<vsq; m++) v[m] += z[m];
}
free(z);
}
void MLEplusStat(double *x, cov_model *cov, double *v){
cov_model *sub;
if (ELEMENTNR_PLUS >= 0) {
sub = cov->sub[ELEMENTNR_PLUS];
CovList[sub->nr].cov(x, sub, v);
} else {
plusStat(x, cov, v); // !!! cov not next
}
// printf("plus %s %d %f, v=%f\n", CovList[sub->nr].name, ELEMENTNR_PLUS, *x, *v);
}
void MLEplusNonStat(double *x, double *y, cov_model *cov, double *v){
cov_model *sub;
if (ELEMENTNR_PLUS >= 0) {
sub = cov->sub[ELEMENTNR_PLUS];
CovList[sub->nr].nonstat_cov(x, y, sub, v);
} else {
plusNonStat(x, y, cov, v); // !!! cov not next
}
}
void Dplus(double *x, cov_model *cov, double *v){
cov_model *sub;
double v1;
int n = cov->nsub, i;
*v = 0.0;
for (i=0; i<n; i++) {
sub = cov->sub[i];
CovList[sub->nr].D(x, sub, &v1);
(*v) += v1;
}
}
void DDplus(double *x, cov_model *cov, double *v){
cov_model *sub;
double v1;
int n = cov->nsub, i;
*v = 0.0;
for (i=0; i<n; i++) {
sub = cov->sub[i];
CovList[sub->nr].D2(x, sub, &v1);
(*v) += v1;
}
}
int checkplus(cov_model *cov) {
int err;
if ((err = checkplusmal(cov)) != NOERROR) {
return err;
}
if (cov->statIn == STAT_MISMATCH) XERR(ERRORNOVARIOGRAM);
return NOERROR;
// spectral mit "+" funktioniert, falls alle varianzen gleich sind,
// d.h. nachfolgend DOLLAR die Varianzen gleich sind oder DOLLAR nicht
// auftritt; dann zufaellige Auswahl unter "+"
}
int initspectralplus(cov_model *cov) {
// #define spec_ergodic !true
int i;
cov_model *sub;
spec_covstorage *cs = &(cov->spec);
double *sd_cum = cs->sub_sd_cum;
// if (spec_ergodic) return ERRORFAILED;
for (i=0; i<cov->nsub; i++) {
sub = cov->sub[i];
CovList[sub->nr].initspectral(sub);
CovList[sub->nr].cov(ZERO, sub, sd_cum + i);
if (i>0) sd_cum[i] += sd_cum[i-1];
}
return NOERROR;
}
void spectralplus(cov_model *cov, spectral_storage *s, double *e){
int nr;
double dummy;
spec_covstorage *cs = &(cov->spec);
double *sd_cum = cs->sub_sd_cum;
nr = cov->nsub - 1;
dummy = UNIFORM_RANDOM * sd_cum[nr];
while (nr > 0 && dummy <= sd_cum[nr - 1]) nr--;
cov_model *next = cov->sub[nr];
CovList[next->nr].spectral(next, s, e);
}
void rangeplus(cov_model *cov, range_arraytype* ra){
range_type *range = ra->ranges;
range->finiterange = true;
range->maxdim = INFDIM;
}
void plus_destruct(void ** S) {
if (*S!=NULL) {
free(*S);
*S = NULL;
}
}
int initplus(method_type *meth){
cov_model *cov=meth->cov;
int m, incomp, pos_incomp=-1, err;
/*
pref_type pref;
for (m=0; m<Forbidden; m++) pref[m] = PREF_BEST;
if (meth->cov->user[0] == 0 || meth->cov->user[1] == 0) {
//PrintModelInfo(meth->cov); assert(false);
// i.e. user defined
pref_type pref;
pref[CircEmbed] = pref[TBM2] = pref[TBM3] = pref[Direct] = pref[Sequential]
= PREF_NONE;
for (m=0; m<Nothing; m++) { // korrekt auch fuer MaxStable?
// printf("%d %d\n", m, pref[m]);
// printf("%d %d\n", meth->cov->user[m]);
if (pref[m] > 0 && meth->cov->user[m] > 0) {
break;
}
}
if (m == Nothing) return ERRORSUBMETHODFAILED;
}
*/
SET_DESTRUCT(plus_destruct);
incomp = 0;
meth->nsub = cov->nsub; // could be improved somewhen in future
for (m=0; m<cov->nsub; m++) {
// hole m-tes element von "plus"; ersetze "plus" durch "identity" --
// kann man besser machen
meth->sub[m] = (method_type*) malloc(sizeof(method_type));
method_type *sub = meth->sub[m];
METHOD_NULL(sub);
cpyMethod(meth, sub, true);
// hier sollte nicht gelinkt, sondern kopiert werden,
// dann koente obiges pref verwendet werden, um
// gewisse Verfahren durch minimumsbildung der prefs
// auszublenden. Erst dann interessant, wenn User
// mehrer Moeglichkeiten angeben kann.
sub->cov = cov->sub[m];
// printf("initplus:");
// PrintModelInfo(sub->cov);
if (meth->gp->general.printlevel >= 5) {
PRINTF(" trying initialisation of submodel #%d (initstandard).\n", m);
}
err = initstandard(sub);
if (err != NOERROR) return err;
if (!sub->compatible) {
pos_incomp = m;
incomp ++;
}
}
meth->compatible = incomp != 1;
if (!meth->compatible && pos_incomp > 0) {
method_type *dummy;
dummy = meth->sub[pos_incomp];
meth->sub[pos_incomp] = meth->sub[0];
meth->sub[0] = dummy;
} else {
meth->S = (incomp > 1)
? (double*) malloc(meth->loc->totalpoints * sizeof(double))
: NULL;
}
char plussign[] = "+";
meth->nr = getmodelnr(plussign);
meth->domethod = doplus;
return NOERROR;
}
void doplus(method_type *meth, res_type *res){
int m;
method_type **sub=meth->sub;
if (meth->S == NULL) {
// assert(false);
for (m=0; m<meth->nsub; m++) {
sub[m]->domethod(sub[m], res);
}
} else {
int i, t=meth->loc->totalpoints;
m = 0;
sub[m]->domethod(sub[m], res);
// printf("doplus %f\n", (double) res[0]);
for (m=1; m<meth->nsub; m++) {
//
// printf("%d doplus comp %d %f\n", m, sub[m]->compatible, (double) res[0]);
if (sub[m]->compatible) {
sub[m]->domethod(sub[m], res);
} else {
for(i=0; i<t; i++)((double *)meth->S)[i] = 0.0;
sub[m]->domethod(sub[m], (res_type *) meth->S);
for(i=0; i<t; i++) res[i] += ((res_type *)meth->S)[i];
// printf("%d doplus non comp %f\n", m, res[0], ((double *)meth->S)[0]);
}
}
}
}
void malStat(double *x, cov_model *cov, double *v){
cov_model *sub;
int i, m,
nsub=cov->nsub,
vsq = cov->vdim * cov->vdim;
double *z = (double*) malloc(sizeof(double) * vsq);
assert(x[0] >= 0.0 || cov->xdim > 1);
for (m=0; m<vsq; m++) v[m] = 1.0;
for(i=0; i<nsub; i++) {
sub = cov->sub[i];
CovList[sub->nr].cov(x, sub, z);
for (m=0; m<vsq; m++) v[m] *= z[m];
}
free(z);
}
void malNonStat(double *x, double *y, cov_model *cov, double *v){
cov_model *sub;
int i, m, nsub=cov->nsub,
vsq = cov->vdim * cov->vdim;
double *z = (double*) malloc(sizeof(double) * vsq);
for (m=0; m<vsq; m++) v[m] = 1.0;
for(i=0; i<nsub; i++) {
sub = cov->sub[i];
CovList[sub->nr].nonstat_cov(x, y, sub, z);
for (m=0; m<vsq; m++) v[m] *= z[m];
}
free(z);
}
int checkmal(cov_model *cov) {
cov_model *next1 = cov->sub[0];
cov_model *next2 = cov->sub[1];
double *aniso1 = next1->p[2], *aniso2 = next2->p[2];
int err;
if ((err = checkplusmal(cov)) != NOERROR) return err;
if (cov->statIn == STAT_MISMATCH ||
(cov->statIn != STATIONARY &&
cov->statIn != COVARIANCE)
) {
return ERRORNOVARIOGRAM;
}
cov->pref[TBM2] = 0;
if (cov->xdim >= 2) cov->pref[TBM3] = 0;
if (cov->xdim==2 && cov->nsub == 2 &&
next1->nr >= DOLLAR && next1->nr <= LASTDOLLAR &&
next2->nr >= DOLLAR && next2->nr <= LASTDOLLAR) {
if (aniso1[0] == 0.0 && next1->ncol[2] == 1) {
cov->pref[TBM2] = next2->pref[TBM2];
cov->pref[TBM3] = next2->pref[TBM3];
} else if (aniso2[0] == 0.0 && next2->ncol[2] == 1) {
cov->pref[TBM2] = next1->pref[TBM2];
cov->pref[TBM3] = next1->pref[TBM3];
}
}
return NOERROR;
}
void Dmal(double *x, cov_model *cov, double *v){
cov_model *sub;
cov_fct *C;
double c[MAXSUB], d[MAXSUB];
int n = cov->nsub, i;
for (i=0; i<n; i++) {
sub = cov->sub[i];
C = CovList + sub->nr;
C->cov(x, sub, c + i);
C->D(x, sub, d + i);
}
*v = 0.0;
for (i=0; i<n; i++) {
double zw = d[i];
int j;
for (j=0; j<n; j++) if (j!=i) zw *= c[j];
(*v) += zw;
}
}
void rangemal(cov_model *cov, range_arraytype* ra){
range_type *range = ra->ranges;
range->finiterange = true;
range->maxdim = INFDIM;
}
int initmal(method_type *meth){
// int err;
// return err;
assert(false);
meth->domethod = domal;
char timessign[] = "*";
meth->nr = getmodelnr(timessign);
return ERRORFAILED;
}
void domal(method_type *meth, res_type *res){
assert(false);
}
void location_rules(method_type *meth, pref_type pref) {
// 1. rules that depend on the the locations and the user's preferences only,
// but not on the covariance model
location_type *loc = meth->loc;
decision_param *dp = &(meth->gp->decision);
// direct_param *lp = &(meth->gp->direct);
unsigned int maxmem=500000000;
int i;
SimulationType Standard[Nothing] = {
CircEmbed, CircEmbedIntrinsic, CircEmbedCutoff, SpectralTBM, TBM2, TBM3,
Direct, Sequential, Markov, Average, Nugget, RandomCoin, Hyperplane
};
for (i=0; i<Nothing; i++) {
pref[Standard[i]] = Nothing - i;
}
// if (loc->totalpoints > max_dirct) pref[Direct] = LOC_PREF_NONE - 0;
if (dp->stationary_only == DECISION_TRUE) {
pref[CircEmbedIntrinsic] = LOC_PREF_NONE - 1;
}
if (dp->exactness==DECISION_TRUE) {
pref[TBM3] = pref[TBM2] = pref[SpectralTBM] = pref[Average] =
pref[Markov] =
pref[Sequential] = pref[RandomCoin] = pref[Hyperplane]
= LOC_PREF_NONE - 2;
}
if (loc->grid) {
if (dp->exactness==DECISION_FALSE &&
loc->totalpoints * (1 << meth->cov->tsdim) * sizeof(double) >
maxmem){
pref[CircEmbed] -= Nothing;
pref[CircEmbedIntrinsic] -= Nothing;
pref[CircEmbedCutoff] -= Nothing;
}
} else {
pref[CircEmbed] = pref[CircEmbedIntrinsic] = pref[CircEmbedCutoff] =
pref[Markov] = LOC_PREF_NONE - 3;
if (!loc->Time) pref[Sequential] = LOC_PREF_NONE;
}
}
void mixed_rules(method_type *meth, pref_type locpref,
pref_type pref, int *order) {
location_type *loc = meth->loc;
direct_param *lp = &(meth->gp->direct);
decision_param *dp = &(meth->gp->decision);
// ce_param *cp = &(meth->gp->ce);
cov_model *cov = meth->cov;
int *covpref = cov->pref;
cov_fct *cf = CovList + cov->nr;
int i,
best_dirct=lp->bestvariables,
max_dirct=lp->maxvariables;
for (i=0; i<Nothing; i++) {
pref[i] = (covpref[i] > PREF_NONE && locpref[i] > LOC_PREF_NONE)
? covpref[i] * Nothing + locpref[i]
: locpref[i] <= LOC_PREF_NONE ? locpref[i] : LOC_PREF_NONE - 4;
}
if (loc->totalpoints * cov->vdim > max_dirct) pref[Direct] = LOC_PREF_NONE-0;
if (loc->totalpoints * cov->vdim <= best_dirct && covpref[Direct] == PREF_BEST)
pref[Direct] = LOC_PREF_BEST;
if (dp->exactness != DECISION_FALSE && cov->tbm2num)
pref[TBM2] = LOC_PREF_NONE - 5;
if (dp->stationary_only==DECISION_CASESPEC && (cf->stationary==STATIONARY))
pref[CircEmbedIntrinsic] = LOC_PREF_NONE - 6;
orderingInt(pref, Nothing, 1, order);
}
char PREF_FAILURE[100 * Nothing];
void standard_destruct(void ** S) {
assert(false);
}
int initstandard(method_type *meth){
globalparam *gp = meth->gp;
// decision_param *lp = &(gp->decision);
pref_type locpref, pref;
int order[Nothing], i,
err = ERROROUTOFMETHODLIST,
errSub = NOERROR;
SimulationType unimeth;
int PL = gp->general.printlevel;
char dummy[100 * Nothing];
static char FailureMsg[][80] =
{"total number of points > maximum value",
"non-stationary model not allowed",
"not an exact method as required by user",
"locations not on a grid",
"denied by cov. model or by user's pref.",
"no analytic solutn of Abelian integral",
"intrinsic fields denied by user"
};
assert(meth->destruct==NULL && meth->S==NULL);
char undefined[] = "undefined";
meth->nr = getmodelnr(undefined);
location_rules(meth, locpref);
mixed_rules(meth, locpref, pref, order);
// printf("\n **** Entering InitStandard\n"); PrintModelInfo(meth->cov);
// PrintMethodInfo(meth); assert(false);
if (PL > 4) {
PRINTF("\n");
for (i=0; i < Nothing; i++) {
PRINTF("%-15s: covprev=%1d locpref=%4d totpref=%6d\n",
METHODNAMES[i], meth->cov->pref[i],
(locpref[i] < -9000) ? -999 : locpref[i], pref[i]);
}
PRINTF("initstandard %s (%d) [pref value %d]\n",
CovList[meth->cov->nr].name, meth->cov->nr,
pref[order[Nothing -1]]);
}
// if (pref[order[Nothing -1]] <= 0)
// return ERROROUTOFMETHODLIST;
i = Nothing - 1;
// printf("hhhhhhhhhhhhhh %d %d %d\n", i, pref[order[i]], PREF_NONE);
for (i = Nothing - 1; i>=0 && pref[order[i]] > PREF_NONE; i--) {
// printf("ggggggggggggggggggggggggg %d\n", i);
unimeth = (SimulationType) order[i];
if (PL > 2) PRINTF("%s : pref=%d\n", METHODNAMES[unimeth], pref[unimeth]);
meth->nr = -unimeth-1;
meth->compatible = compatible_primitive[unimeth];
meth->domethod = do_method[unimeth];
// print("%d\n", unimeth);
err = init_method[unimeth](meth); //!!
// printf("i= %d %d\n", order[i], err);
// PrintMethodInfo(meth); assert(false);
if (PL >= 5)
PRINTF("%d , err =%d [%d, %s]\n", i, err, unimeth, METHODNAMES[unimeth]);
if (err == NOERROR) {
if (PL >= 5) PRINTF("returning to higher level...\n");
return NOERROR;
}
assert(meth->destruct != NULL);
meth->destruct(&(meth->S));
meth->destruct = NULL;
}
// all failed;
int nr = meth->cov->nr;
if (gp->general.printlevel >= 5) {
PRINTF(" trying direct initialisation of model `%s' [%d; %ld].\n",
CovList[nr].name, nr, CovList[nr].initmethod);
}
if (CovList[nr].initmethod == NULL) {
return ERRORNOTDEFINED;
}
// PrintMethodInfo(meth); assert(false);
if ((errSub = CovList[nr].initmethod(meth)) != NOERROR) {
if (errSub == ERRORSUBMETHODFAILED || errSub == ERROROUTOFMETHODLIST) {
// printf("err = %d %d\n", err, errSub);
return err; // not subErr !
}
strcpy(PREF_FAILURE, "");
int p, lp;
#define NMAX 14
char lpd[255], pd[255], names[NMAX];
names[NMAX-1] = '\0';
if (gp->general.printlevel >= 5) {
for (i=0; i<Nothing; i++) {
lp = locpref[i] - LOC_PREF_NONE;
p = pref[i] - LOC_PREF_NONE;
if (lp>0) {
strcpy(lpd, "");
} else {
sprintf(lpd, "%s (locp) ", FailureMsg[-lp]);
}
if (p>0 || p == lp) {
strcpy(pd, ""); // strcpy(pd, "(method specific failure)");
} else {
sprintf(pd, "%s (pref)", FailureMsg[-p]);
}
strncpy(names, METHODNAMES[i], NMAX-1);
sprintf(dummy, "%s %-13s: %s%s\n", PREF_FAILURE, names, lpd, pd);
strcpy(PREF_FAILURE, dummy);
}
}
return errSub;
}
return NOERROR;
}
void dostandard(method_type *meth, res_type *res){
assert(false);
meth->sub[0]->domethod(meth, res);
}
int init_nothing(method_type *meth) {
assert(false);
return ERRORFAILED;
}
void do_nothing(method_type *meth, res_type *res){
assert(false);
}