https://github.com/cran/RandomFields
Revision c751cbeafa6661ec449a5a53a8b3e659f558be70 authored by Martin Schlather on 27 May 2005, 00:00:00 UTC, committed by Gabor Csardi on 27 May 2005, 00:00:00 UTC
1 parent 7669be7
Raw File
Tip revision: c751cbeafa6661ec449a5a53a8b3e659f558be70 authored by Martin Schlather on 27 May 2005, 00:00:00 UTC
version 1.2.16
Tip revision: c751cbe
RFspectral.cc
/*
 Authors
 Martin Schlather, schlath@hsu-hh.de

 Simulation of a random field by spectral turning bands

 Copyright (C) 2000 -- 2005 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 <stdio.h>  
#include <stdlib.h>
#include "RFsimu.h"
#include "RFCovFcts.h"
#include <assert.h>


int SPECTRAL_LINES=500; 
bool SPECTRAL_GRID=true;


void SetParamSpectral(int *action,int *nLines, int *grid) {
  switch (*action) {
  case 0 :
    SPECTRAL_LINES=*nLines; 
    SPECTRAL_GRID=(bool) *grid;
    break;
  case 1 :
    *nLines=SPECTRAL_LINES; 
    *grid= (int) SPECTRAL_GRID ;
    if (GetNotPrint)   break;
  case 2 : 
    PRINTF("\nSpectral\n========\nnLines=%d\ngrid=%d\n",
	   SPECTRAL_LINES,SPECTRAL_GRID);
    break;
  default : PRINTF(" unknown action\n"); 
  } 
}

typedef struct spectral_storage {
  param_type param;
  randommeasure randomAmplitude[MAXCOV];
  double *x;
  int actcov;
  bool grid;
  int TrueDim;
} spectral_storage;

void spectral_destruct(void **S) 
{ 
  if (*S!=NULL) {
    spectral_storage *x;
    x =  *((spectral_storage**)S);
    if (x->x!=NULL) free(x->x);
    free(*S);   
    *S = NULL;
  }
}

int init_simulatespectral(key_type *key, int m)
{
  spectral_storage *s;
  int Xerror,  v, start_param[MAXDIM], index_dim[MAXDIM];
  bool no_last_comp;
  cov_fct *cov;
  unsigned short int actcov;
  int covnr[MAXCOV];
  int multiply[MAXCOV];
  double store_param[TOTAL_PARAM];
  long bytes;
  bool noerror_repeat;
  
  SET_DESTRUCT(spectral_destruct);
  if ((key->S[m]=malloc(sizeof(spectral_storage)))==0){
    Xerror=ERRORMEMORYALLOCATION; goto ErrorHandling;
  }
  s = (spectral_storage*)key->S[m];
  s->x = NULL;

  if (key->Time) {Xerror=ERRORTIMENOTALLOWED; goto ErrorHandling;}

  noerror_repeat = key->anisotropy;
  bytes = key->timespacedim * key->timespacedim;


  //FC1(SpectralTBM, spectral, s->param);
  actcov=0;
  { 
    int v;
    for (v=0; v<key->ncov; v++) {
      if ((key->method[v]==SpectralTBM) && (key->left[v])) {
	// Variance==0 is not eliminated anymore !! -- maybe this could be improved
	key->left[v] = false;
	assert((key->covnr[v] >= 0) && (key->covnr[v] < currentNrCov));
	assert(key->param[v][VARIANCE] >= 0.0);
	covnr[actcov] = key->covnr[v];
	if (CovList[covnr[actcov]].implemented[SpectralTBM] <= NOT_IMPLEMENTED) {
	  Xerror=ERRORNOTDEFINED; goto ErrorHandling;}
	memcpy(s->param[actcov], key->param[v], sizeof(double) * key->totalparam);
	if (actcov>0) {
	  if ((multiply[actcov-1] = key->op[v-1]) && 
	      key->method[v-1] != SpectralTBM){
	    if (GENERAL_PRINTLEVEL>0) 
	      PRINTF("severe error - contact author. %d %d %d %d (%s) %d (%s)\n",
		     v, key->op[v-1], key->ncov, key->method[v-1],
		     METHODNAMES[key->method[v-1]],
		     SpectralTBM, METHODNAMES[SpectralTBM]);
	    Xerror=ERRORMETHODMIX; goto ErrorHandling;
	  }
	}
  // end FC1
	if (key->anisotropy) {
	  if (actcov>0) { 
	    if (memcmp(store_param, &(s->param[actcov][ANISO]), bytes) ||
		(store_param[VARIANCE] != s->param[actcov][VARIANCE])) {
	      key->left[v]=true; actcov--;}
	  } else {
	    memcpy(store_param, &(s->param[actcov-1][ANISO]), bytes);
	    store_param[VARIANCE] = s->param[actcov][VARIANCE];
	  }
	} else {
	  assert(fabs(key->param[v][SCALE] * key->param[v][INVSCALE]-1.0)
		 < EPSILON);
	  if (actcov>0) { 
	    if (store_param[VARIANCE] != s->param[actcov][VARIANCE]){
	      key->left[v]=true; 
	      noerror_repeat= true;
	      actcov--;
	    }
	  } else {
	    store_param[VARIANCE] = s->param[actcov][VARIANCE];
	  }
	}
  // FC2;
	actcov++;
      }
    }
  }
  if (actcov==0) { /* no covariance for the considered method found */
    Xerror=NOERROR_ENDOFLIST;
    goto ErrorHandling;
  }
 //end FC2 

  s->grid = key->grid && !key->anisotropy;
  s->actcov = actcov;
  for (v=0; v<actcov; v++) s->randomAmplitude[v] = CovList[covnr[v]].spectral;
  GetTrueDim(key->anisotropy, key->timespacedim, s->param[0],
	     &(s->TrueDim), &no_last_comp, start_param, index_dim); 
  if ((Xerror=Transform2NoGrid(key, s->param[0], s->TrueDim, 
			       start_param, &(s->x))) != NOERROR)
    goto ErrorHandling; 
  if (s->TrueDim > 2) {Xerror=ERRORWRONGDIM; goto ErrorHandling;}
  if (s->TrueDim == 0) {Xerror=ERRORTRIVIAL; goto ErrorHandling;}
  for (v=0; v<actcov; v++) {
    cov = &(CovList[covnr[v]]);
    if ((cov->check!=NULL) && 
	(Xerror=cov->check(s->param[v], s->TrueDim, SpectralTBM)))
      goto ErrorHandling;
  }
  if (noerror_repeat) return NOERROR_REPEAT;
  else return 0;
 
 ErrorHandling:
  return Xerror;
}

void do_simulatespectral(key_type *key, int m, double *res ) 
  // in two dimensions only!
{  
  int k, nx, ny, v;
  double phi=RF_INF, phistep=RF_INF, sqrttwodivbyn, VV;  //initialisation not used
  spectral_storage *s;
  
  assert(key->active);
  s = (spectral_storage*)key->S[m];
  assert((s->TrueDim==1) || (s->TrueDim==2));

  sqrttwodivbyn = sqrt(s->param[0][VARIANCE]*2.0/ (double) SPECTRAL_LINES);  
  
  /* are the angles of the lines situated on a grid or random?
     if grid, then the step of the angle is 2\pi / SPECTRAL_LINES.
  */
  if (SPECTRAL_GRID) {
    phistep=TWOPI/ (double) SPECTRAL_LINES; 
    phi=phistep*UNIFORM_RANDOM;
  }
  {
    register long i,endfor;
    endfor = key->totalpoints;
    for (i=0; i<endfor; i++) { res[i]=0.0; }
  }
  v = (int) (UNIFORM_RANDOM * (double) s->actcov);
  

  //the very procedure:
  if (s->TrueDim==1) {
   if (s->grid) {
      long zaehler;
      double incx, segx;
      for(k=0; k<SPECTRAL_LINES; k++){
	double cp,Amp;            
	v = (v+1) % s->actcov;
	Amp=  s->param[v][INVSCALE] * 
	  (s->randomAmplitude[v])(s->param[v] ); 
	if (SPECTRAL_GRID) {phi+=phistep;} else {phi=TWOPI*UNIFORM_RANDOM;}  
	VV = TWOPI*UNIFORM_RANDOM;
	cp = Amp * cos(phi);  
	zaehler=0;      
	segx = VV + key->x[0][XSTART] * cp;
	incx=key->x[0][XSTEP]*cp; 
	for (nx=0; nx<key->length[0]; nx++) {
	  res[zaehler++] += cos(segx);	  
	  segx += incx;
	}
      }
    } else { // no grid
      for(k=0; k<SPECTRAL_LINES; k++){
	double cp,Amp;
	v = (v+1) % s->actcov;
	Amp= (s->randomAmplitude[v])(s->param[v] ); 
	if (SPECTRAL_GRID) {phi+=phistep;} else {phi=TWOPI*UNIFORM_RANDOM;}  
	VV = TWOPI*UNIFORM_RANDOM;
	cp = Amp * cos(phi);    
	for (nx=0; nx<key->totalpoints; nx++) {	
	  res[nx] += cos(cp * s->x[nx] + VV);
	}
      }		      
    }
  } else {

    if (s->grid) {
      long zaehler;
      double incx, incy, segx, segy;
      for(k=0; k<SPECTRAL_LINES; k++){
	double cp,sp,Amp;            
	v = (v+1) % s->actcov;
	Amp=  s->param[v][INVSCALE] * 
	  (s->randomAmplitude[v])(s->param[v] ); 
	if (SPECTRAL_GRID) {phi+=phistep;} else {phi=TWOPI*UNIFORM_RANDOM;}  
	VV = TWOPI*UNIFORM_RANDOM;
	cp=Amp * cos(phi);   sp=Amp * sin(phi); 

	zaehler=0;      
	segy=VV + key->x[0][XSTART] * cp + key->x[1][XSTART]*sp;
	incx=key->x[0][XSTEP]*cp; incy=key->x[1][XSTEP]*sp; 
	for (ny=0; ny<key->length[1]; ny++) {	
	  segx = segy;
	  for (nx=0; nx<key->length[0]; nx++) {
	    res[zaehler++] += cos(segx);	  
	    segx+=incx;
	  }
	  segy += incy;
	}
      }
    } else { // no grid
      int twonx;
      for(k=0; k<SPECTRAL_LINES; k++){
	double cp,sp,Amp;
	v = (v+1) % s->actcov;
	Amp= (s->randomAmplitude[v])(s->param[v] ); 
	if (SPECTRAL_GRID) {phi+=phistep;} else {phi=TWOPI*UNIFORM_RANDOM;}  
	VV = TWOPI*UNIFORM_RANDOM;
	cp=Amp * cos(phi);   sp=Amp * sin(phi); 
	for (nx=0; nx<key->totalpoints; nx++) {	
	  twonx = nx << 1;
	  res[nx] += cos(cp * s->x[twonx] + sp * s->x[twonx+1] + VV);
	}
      }		      
    }
  }
  for (nx=0; nx<key->totalpoints; nx++) { res[nx] = res[nx]*sqrttwodivbyn; }  
}
  








back to top