0

Following up from an R blog which is interesting and quite useful to simulate the time series of an unknown area using its Weibull parameters.

Although this method gives a reasonably good estimate of time series as a whole it suffers a great deal when we look for seasonal changes. To account for seasonal changes I want to employ seasonal maximum wind speeds and carry out the time series synthesis such that the yearly distribution remains constant ie. shape and scale parameters (annual values).

I want to employ seasonal maximum wind speeds to the below code by using 12 different maximum wind speeds, one each for every month. This will allow greater wind speeds at certain month and lower in others and should even out the resultant time series.

The code follows like this:

MeanSpeed<-7.29 ## Mean Yearly Wind Speed at the site.

Shape=2; ## Input Shape parameter (yearly).
Scale=8 ##Calculated Scale Parameter ( yearly).

MaxSpeed<-17 (##yearly)
## $$$ 12 values of these wind speed one for each month to be used. The resultant time series should satisfy shape and scale parameters $$ ###
nStates<-16 

nRows<-nStates;
nColumns<-nStates;


LCateg<-MaxSpeed/nStates; 


WindSpeed=seq(LCateg/2,MaxSpeed-LCateg/2,by=LCateg) ## Fine the velocity vector-centered on the average value of each category.

##Determine Weibull Probability Distribution.
wpdWind<-dweibull(WindSpeed,shape=Shape, scale=Scale); # Freqency distribution.

plot(wpdWind,type = "b", ylab= "frequency", xlab = "Wind Speed")  ##Plot weibull probability distribution.

norm_wpdWind<-wpdWind/sum(wpdWind); ## Convert weibull/Gaussian distribution to normal distribution.

## Correlation between states (Matrix G)
g<-function(x){2^(-abs(x))} ## decreasing correlation function between states.
G<-matrix(nrow=nRows,ncol=nColumns)
G <- row(G)-col(G)
G <- g(G)

##--------------------------------------------------------


## iterative process to calculate the matrix P (initial probability)
P0<-diag(norm_wpdWind);   ## Initial value of the MATRIX P.
P1<-norm_wpdWind;  ## Initial value of the VECTOR p.


## This iterative calculation must be done until a certain error is exceeded
## Now, as something tentative, I set the number of iterations

steps=1000;  
P=P0; 
p=P1; 

for (i in 1:steps){
    r<-P%*%G%*%p;
    r<-as.vector(r/sum(r)); ## The above result is in matrix form. I change it to vector
    p=p+0.5*(P1-r)
    P=diag(p)}

   ## $$ ----Markov Transition Matrix --- $$ ##

N=diag(1/as.vector(p%*%G));## normalization matrix

MTM=N%*%G%*%P ## Markov Transition Matrix

MTMcum<-t(apply(MTM,1,cumsum));## From the MTM generated the accumulated

##-------------------------------------------
## Calculating the series from the MTMcum

##Insert number of data sets. 
LSerie<-52560; Wind Speed every 10 minutes for a year. 

RandNum1<-runif(LSerie);## Random number to choose between states
State<-InitialState<-1;## assumes that the initial state is 1 (this must be changed when concatenating days)
StatesSeries=InitialState;

## Initallise----

## The next state is selected to the one in which the random number exceeds the accumulated probability value
##The next iterative procedure chooses the next state whose random number is greater than the cumulated probability defined by the MTM
for (i in 2:LSerie) {
  ## i has to start on 2 !!
    State=min(which(RandNum1[i]<=MTMcum[State,]));

    ## if (is.infinite (State)) {State = 1}; ## when the above condition is not met max -Inf
    StatesSeries=c(StatesSeries,State)}

RandNum2<-runif(LSerie); ## Random number to choose between speeds within a state

SpeedSeries=WindSpeed[StatesSeries]-0.5+RandNum2*LCateg;
##where the 0.5 correction is needed since the the WindSpeed vector is centered around the mean value of each category.


print(fitdistr(SpeedSeries, 'weibull')) ##MLE fitting of SpeedSeries

Can anyone suggest where and what changes I need to make to the code?

SamAct
  • 529
  • 4
  • 23

1 Answers1

0

I don't know much about generating wind speed time series but maybe those guidelines can help you improve your code readability/reusability:

#1 You probably want to have a function which will generate a wind speed time serie given a number of observations and a seasonal maximum wind speed. So first try to define your code inside a block like this one:

wind_time_serie <- function(nobs, max_speed){
    #some code here
}

#2 Doing so, if it seems that some parts of your code are useful to generate wind speed time series but aren't about wind speed time series, try to put them into functions (e.g. the part you compute norm_wpdWind, the part you compute MTMcum,...).

#3 Then, the part of your code at the beginning when your define global variable should disappear and become default arguments in functions.

#4 Avoid using endline comments when your line is already long and delete the ending semicolumns.

#This
  State<-InitialState<-1;## assumes that the initial state is 1 (this must be changed when concatenating days)

#Would become this:
  #Assumes that the initial state is 1 (this must be changed when concatenating days)
  State<-InitialState<-1

Then your code should be more reusable / readable by other people. You have an example below of those guidelines applied to the rnorm part:

  norm_distrib<-function(maxSpeed, states = 16, shape = 2, scale = 8){

    #Fine the velocity vector-centered on the average value of each category.
    LCateg<-maxSpeed/states
    WindSpeed=seq(LCateg/2,maxSpeed-LCateg/2,by=LCateg) 

    #Determine Weibull Probability Distribution.
    wpdWind<-dweibull(WindSpeed,shape=shape, scale=scale)

    #Convert weibull/Gaussian distribution to normal distribution.
    return(wpdWind/sum(wpdWind))

  }

  #Plot normal distribution with the max speed you want (e.g. 17)
  plot(norm_distrib(17),type = "b", ylab= "frequency", xlab = "Wind Speed")