Nothing
#install.packages("pracma") #install.packages("matlib") #install.packages("NlcOptim") #library("pracma") #library("matlib") #sample data #mosquito count from data y_in = c(15, 40, 45, 88, 99, 145, 111, 132, 177, 97, 94, 145, 123, 111, 125, 115, 155, 160, 143, 132, 126, 125, 105, 98, 87, 54, 55, 8) #day of year in which measurments making up yin occur, Jan 1st = day 1 t_in_user = c(93, 100, 107, 114, 121, 128, 135, 142, 149, 163, 170, 177, 184, 191, 198, 205, 212, 219, 226, 233, 240, 247, 254, 261, 267, 274, 281, 288) if (length(y_in) != length(t_in_user)){ stop("input data mismatch") }
# User inputs (aside from trap data inputs) #mu = natural mosquito death rate mu = 1/14 #program should set mu = 1 / tau_mosq, where tau_mosq is the mosquito lifetime input by user in units of days # tau_mosq should be bounded between 1 and 30 #m = number of mosquito lifetimes for population decay between seasons.. m = 3 #this will be input by the user, and must be an integer greater than 2, upperbound 100, default value 3 # N_lam = max fourier mode order to calculate N_lam = 25; #user input between 1 and 200, default value 25 (I referred to this as jmax over Skype - JD)
#setting up time and trap count vectors to fit the model to #first round user time inputs to integer values t_in = round(t_in_user) #defining N0 = number of input data points (not a user input) N0 = length(y_in) #defining vector of time differences to be used later (not a user input) delta_t_in = numeric(N0-1) for (i in 1:(N0-1)){ delta_t_in[i] = t_in[i+1]-t_in[i] if (delta_t_in[i] < 0) stop("non-increasing measurement times") } #N_pts = number of points in extended data set, N_pts = N0 + 3 always (not a user input) N_pts = N0 + 3 #defining extended trap count and time data vectors t_dat = numeric(N_pts) if (t_in[1] - m / mu > 0){ y_dat = c(0,0, y_in,0) t_dat[1] = 0 t_dat[2] = (m -1) / mu for (i in 3 : (N_pts - 1)){ t_dat[i] = t_in[i - 2] - t_in[1] + m / mu } t_dat[N_pts] = t_dat[N_pts - 1] + (m) / mu t_dat=matrix(t_dat, ncol=1) } else { y_dat = c(0, y_in, 0, 0) t_dat[1] = 0 for (i in 2: (N_pts - 2)){ t_dat[i] = t_in[i - 1] } t_dat[N_pts - 1] = t_dat[N_pts - 2] + (2*(m - 1)) / mu - t_dat[2] t_dat[N_pts] = t_dat[N_pts - 1] + 1 / mu } #extended vector of time differences delta_t_dat = numeric(N_pts) for (i in 1 : (N_pts - 1)){ delta_t_dat[i] = t_dat[i + 1] - t_dat[i] } delta_t_dat[N_pts] = 0 delta_t_dat= matrix(delta_t_dat,ncol=1) #tau = length of 'season' in days tau = t_dat[N_pts];
#Defining matrices 'J' and 'M' #J matrix and inverse J = matrix(0, nrow= N_pts, ncol=N_pts) for (i in 1 : (N_pts - 1)){ J[i, i] = 1 J[i + 1, i] = -exp(-mu*delta_t_dat[i]) } J[N_pts, N_pts] = 1; J[1, N_pts] = -exp(-mu * delta_t_dat[N_pts]) #M matrix and inverse M = matrix(0, nrow= N_pts, ncol=N_pts) for (i in 2 : (N_pts - 1)){ M[i, i] = (1 - exp( -mu * delta_t_dat[i - 1] ) ) /(mu * delta_t_dat[i - 1] ) - exp( -mu * delta_t_dat[i - 1]) M[i + 1, i] =1- ( 1 - exp(-mu * delta_t_dat[i]) )/(mu * delta_t_dat[i]) } M[N_pts, N_pts] = (1 - exp( (-1)*mu * delta_t_dat[N_pts - 1] ) ) /(mu * delta_t_dat[(N_pts - 1)] ) -exp( -mu * delta_t_dat[(N_pts - 1)]) M[1, N_pts] = 0 M[1, 1] = 0 M[2, 1] = 1- ( 1 - exp(-mu * delta_t_dat[1]) )/(mu * delta_t_dat[(1)]) ###### weighting code code #Weight matrix: diagonal entries to be filled with sqrt(number of counts on day) except for the artifical 0 measurments on end of data W = matrix(0, nrow= N_pts, ncol=N_pts) if( t_in[(1)] - m / mu > 0){ W[1,1] = 1 W[2,2] = 1 W[N_pts,N_pts] = 1 for(i in 3 : N_pts-1){ W[i,i] = sqrt(1) #fill sqrt(number of counts) here } } else { W[1,1] = 1 W[N_pts-1,N_pts-1] = 1 W[N_pts,N_pts] = 1 for(i in 2 : N_pts-2){ W[i,i] = sqrt(1) #fill sqrt(number of counts) here } }
#Obtaining emergence rate vector lambda_dat by contrained optimization Aeq = matrix(numeric(N_pts), nrow=1) Aeq[(1)] = 1 Aeq[(N_pts)] = -1 beq = 0 bineq = numeric(N_pts) lb = numeric(N_pts) ################### objective_fun = function(x) {t( W %*% ( (1 / mu) * (mldivide(J, (M %*% x), pinv = TRUE)) - y_dat) )%*%( W %*% ((1 / mu) * (mldivide(J, (M %*% x), pinv = TRUE)) - y_dat))} lambda_dat = fmincon(numeric(N_pts), objective_fun, gr= NULL, method="SQP", A= (-(1 / mu) *( inv(J) %*% (M))), b=bineq, Aeq = Aeq, beq = beq, lb = lb, ub = NULL) #########
#Calculating emergence rate fourier modes lam_fourier lam_fourier = numeric(N_lam + 1); for (j in 1 : (N_pts-1)){ lam_fourier[1] = lam_fourier[1] + (1 / tau)*( lambda_dat$par[j] + lambda_dat$par[j + 1] ) * delta_t_dat[j] / 2 } #zero mode for (k in 2 : (N_lam + 1)) #non-zero postive modes (negative modes given by complex conjugates of positve modes) { for (j in 1 : (N_pts - 1)){ lam_fourier[(k)] = lam_fourier[(k)] +( ( lambda_dat$par[(j + 1)] - lambda_dat$par[(j)] ) / delta_t_dat[(j)] ) *( tau / (2 * pi * (k-1) ) )* ( ( exp(- 2 * pi * complex(real = 0, imaginary = 1) * (k-1) * t_dat[(j + 1)] / tau ) -exp(- 2 * pi * complex(real = 0, imaginary = 1) * (k-1) * t_dat[(j)]/ tau) ) / (2 * pi * (k-1)) )+ complex(real = 0, imaginary = 1) * ( lambda_dat$par[(j + 1)] * exp(- 2 * pi * complex(real = 0, imaginary = 1) * (k-1) * t_dat[(j + 1)] / tau ) -lambda_dat$par[(j)] * exp(- 2 * pi * complex(real = 0, imaginary = 1) * (k-1) * t_dat[(j)] /tau ) ) / (2 * pi * (k-1) ) } }
#defing functions for optimization code #goto line 1670 or so to skip past all of these definitons #Permutaion function: For a given list of numbers, this function outputs a matrix, where each row is a unique permutation of the list uperm = function(d) { dat <- factor(d) N <- length(dat) n <- tabulate(dat) ng <- length(n) if(ng==1) return(d) a <- N-c(0,cumsum(n))[-(ng+1)] foo <- lapply(1:ng, function(i) matrix(combn(a[i],n[i]),nrow=n[i])) out <- matrix(NA, nrow=N, ncol=prod(sapply(foo, ncol))) xxx <- c(0,cumsum(sapply(foo, nrow))) xxx <- cbind(xxx[-length(xxx)]+1, xxx[-1]) miss <- matrix(1:N,ncol=1) for(i in seq_len(length(foo)-1)) { l1 <- foo[[i]] nn <- ncol(miss) miss <- matrix(rep(miss, ncol(l1)), nrow=nrow(miss)) k <- (rep(0:(ncol(miss)-1), each=nrow(l1)))*nrow(miss) + l1[,rep(1:ncol(l1), each=nn)] out[xxx[i,1]:xxx[i,2],] <- matrix(miss[k], ncol=ncol(miss)) miss <- matrix(miss[-k], ncol=ncol(miss)) } k <- length(foo) out[xxx[k,1]:xxx[k,2],] <- miss out <- out[rank(as.numeric(dat), ties="first"),] foo <- cbind(as.vector(out), as.vector(col(out))) out[foo] <- d t(out) } #this function computes the "P" product and exponentials for a given k P_vals = function(z, rho, Npulse, tau, k){ P_func = function(x){ rho * 1 /(log(1/(1-rho)) - 2 * pi * complex(real = 0, imaginary = 1) * x)} z_vec = matrix(0, nrow = Npulse, ncol = 1); for(i in 1:Npulse){ z_vec[i, 1] = z[i] } #determine number of integer vectors to permute (will be smaller for #only two and three pulses). number of combos = N_terms if (k == 0){ if (Npulse == 2){ N_terms = 5 }else if(Npulse == 3){ N_terms = 7 }else { N_terms = 8 } #create a matrix to hold the integer vectors to permute, and #initialize to zero. Each column will give an integer vector int_vecs = matrix(0, nrow=Npulse, ncol=N_terms); #the first 5 integer vectors have at most two non-zero elements. #This loop replaces the first two zeros in the first 5 columns of int_vecs #with the appropriate integers. for (i in 1:5){ int_vecs[1:2, i] = c((i - 1), -(i -1)) } #if there are are three or more pulses, we need to include #integer vectors with three non-zero terms if (Npulse >= 3){ int_vecs[1:3, 6] = c(2, -1,-1) int_vecs[1:3, 7] = c(-2, 1, 1) } #if there are four or more pulses, then we need to include an #integer vector with four non-zero terms if (Npulse >= 4){ int_vecs[1:4, 8] = c(1, 1, -1,-1) } #calculates the "P" functions for each column of integer combos in #int_vec. "P" function values are independet of integer #permutations. pre_factors is a list which holds the "P"-function #values for each integer combo pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * P_func(int_vecs[m,i]); } } #Now calculate the exponential terms which will multiply the "P"functions in the pre_factors list #post_factors = list of the exponential terms to multiply the # corresponding "P" functions in the pre_factors list post_factors = numeric(N_terms) #initialize to zero for (i in 1: N_terms){ #for each integer combo given by the columns of int_vecs... #calculates the unique permutations of the ith integer combo #int_vecs(:, i) = ith column of int_vecs matrix #perm_list = Nperms x Npulse matrix, where Nperms is the number # of unique permutations of the ith integer combo # Each row of perm_list gives a unique permutaion of the ith integer combo perm_list = uperm(int_vecs[,i]) if( i == 1){ Nperms = 1 }else{ Nperms = length(perm_list[,1]) #number of unique permutations of the ith integer combo } for (m in 1:Nperms){ #for each uniqe permutation of the ith integer combo, add the corresponding exponential to the running total of the corresponding post_factor value if(i == 1){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * (perm_list %*% z) / tau) } else { post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * (perm_list[m,] %*% z) / tau) } }#perm_list[m, ] = mth row of perm_list = mth unique permutaton of ith integer combo } val = 0 for (i in 1:N_terms){ #add together the (pre_factor * post_factor) for each integer combo val = val + pre_factors[1,i] * post_factors[i] } return(val) }else if(abs(k) == 1){ kk = abs(k) if (Npulse == 2){ N_terms = 5 }else{ N_terms = 8 } int_vecs = matrix(0,nrow=Npulse, ncol=N_terms) for (i in 1:5){ int_vecs[1:2, i] = sign(k) * c(kk + (i - 1), -(i -1)) } if (Npulse >= 3){ int_vecs[1:3, 6] = sign(k) * c(1 , 1 , -1) int_vecs[1:3, 7] = sign(k) * c(3 , -1 , -1) int_vecs[1:3, 8] = sign(k) * c(2 , -2 , 1) } pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * P_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] +exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } val = 0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } return(val) } else if(abs(k) == 2){ kk = abs(k) if (Npulse == 2){ N_terms = 5 }else if (Npulse == 3){ N_terms = 6 }else{ N_terms = 7 } int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk + 1, -1) int_vecs[1:2, 4] = sign(k) * c(kk + 2, -2) int_vecs[1:2, 5] = sign(k) * c(kk + 3, -3) if (Npulse >= 3){ int_vecs[1:3, 6] = sign(k) *c(2, -1,1) } if (Npulse >= 4){ int_vecs[1:4, 7] = sign(k) *c(1, 1, 1,-1) } pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * P_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) if(Npulse == 2 && i == 2){ Nperms = 1; post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list %*% z / tau) }else{ Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } } val = 0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } return(val) }else if(abs(k) == 3){ kk = abs(k) if (Npulse == 2){ N_terms = 5 }else{ N_terms = 8 } int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk + 1, -1) int_vecs[1:2, 4] = sign(k) * c(kk + 2, -2) int_vecs[1:2, 5] = sign(k) * c(kk + 3, -3) if (Npulse >= 3){ int_vecs[1:3, 6] = sign(k) *c(1, 1, 1) int_vecs[1:3, 7] = sign(k) *c(3, 1, -1) int_vecs[1:3, 8] = sign(k) *c(2, 2, -1) } pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * P_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) if(Npulse == 3 && i == 6){ Nperms = 1 post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list %*% z / tau) }else{ Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } } val = 0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } return(val) }else if(abs(k) == 4){ kk = abs(k) if (Npulse == 2){ N_terms = 5 }else if(Npulse == 3){ N_terms = 7 }else{ N_terms = 8 } int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk -2, 2) int_vecs[1:2, 4] = sign(k) * c(kk +1, -1) int_vecs[1:2, 5] = sign(k) * c(kk + 2, -2) if (Npulse >= 3){ int_vecs[1:3, 6] = sign(k) *c(4, -1, 1) int_vecs[1:3, 7] = sign(k)*c(2, 1, 1) } if (Npulse >= 4){ int_vecs[1:4, 8] = sign(k) *c(1, 1, 1, 1) } pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * P_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) if(Npulse == 4 && i == 8){ Nperms = 1 post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list %*% z / tau) }else if(Npulse == 2 && i == 3){ Nperms = 1 post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list %*% z / tau) } else{ Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } } val=0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } return(val) }else if(abs(k) == 5){ kk = abs(k) if (Npulse == 2){ N_terms = 5 }else{ N_terms = 7 } int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk -2, 2) int_vecs[1:2, 4] = sign(k) * c(kk + 1, -1) int_vecs[1:2, 5] = sign(k) * c(kk + 2, -2) if (Npulse >= 3){ int_vecs[1:3, 6] = sign(k) *c(2, 2, 1); int_vecs[1:3, 7] = sign(k) *c(3, 1, 1); } pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * P_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } val=0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } return(val) }else if(abs(k) == 6){ kk = abs(k) if (Npulse == 2){ N_terms = 6 }else{ N_terms = 7 } int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk -2, 2) int_vecs[1:2, 4] = sign(k) * c(kk - 3, 3) int_vecs[1:2, 5] = sign(k) * c(kk + 1, -1) int_vecs[1:2, 6] = sign(k) * c(kk + 2, -2) if (Npulse >= 3){ int_vecs[1:3, 7] = sign(k) *c(4, 1, 1) } pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * P_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) if(Npulse == 2 && i == 4){ Nperms = 1 post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list %*% z / tau) }else{ Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } } val=0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } return(val) }else if(abs(k) == 7){ kk = abs(k) N_terms = 6 int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk -2, 2) int_vecs[1:2, 4] = sign(k) * c(kk - 3, 3) int_vecs[1:2, 5] = sign(k) * c(kk + 1, -1) int_vecs[1:2, 6] = sign(k) * c(kk + 2, -2) pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * P_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } val=0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } return(val) }else if(abs(k) == 8){ kk = abs(k) N_terms = 6 int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk -2, 2) int_vecs[1:2, 4] = sign(k) * c(kk + 1, -1) int_vecs[1:2, 5] = sign(k) * c(kk -3, +3) int_vecs[1:2, 6] = sign(k) * c(kk -4, +4) pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * P_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) if(Npulse == 2 && i == 6){ Nperm = 1 post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list %*% z / tau) }else{ Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } } val=0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } return(val) }else if(abs(k) == 9){ kk = abs(k) N_terms = 5 int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk + 1, -1) int_vecs[1:2, 4] = sign(k) * c(kk -2, 2) int_vecs[1:2, 5] = sign(k) * c(kk -3, +3) pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * P_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } val=0 for (i in 1:N_terms){ val = val + pre_factors[i] * post_factors[i] } return(val) }else if(abs(k) == 10){ kk = abs(k) N_terms = 4 int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk + 1, -1) int_vecs[1:2, 4] = sign(k) * c(kk -2, 2) pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * P_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } val=0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } return(val) }else if(abs(k) == 11){ kk = abs(k) N_terms = 4 int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk + 1, -1) int_vecs[1:2, 4] = sign(k) * c(kk -2, 2) pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * P_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } val=0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } out = val } else{ kk = abs(k) N_terms = 3 int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk + 1, -1) pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * P_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } val=0 for (i in 1:N_terms){ val = val + pre_factors[i] * post_factors[i] } return(val) } } #this function computes the "Q" product and exponentials with the fourier modes for a given k Q_vals = function(z, rho, Npulse, tau, j, jj){ Q_func = function(x){ (rho / (1 - rho)) * 1 /(log(1/(1-rho)) + 2 * pi * complex(real = 0, imaginary = 1) * x)} k = -(j + jj) #determine number of integer vectors to permute (will be smaller for #only two and three pulses). number of combos = N_terms if (k == 0){ if (Npulse == 2){ N_terms = 5 }else if(Npulse == 3){ N_terms = 7 }else { N_terms = 8 } #create a matrix to hold the integer vectors to permute, and #initialize to zero. Each column will give an integer vector int_vecs = matrix(0, nrow=Npulse, ncol=N_terms); #the first 5 integer vectors have at most two non-zero elements. #This loop replaces the first two zeros in the first 5 columns of int_vecs #with the appropriate integers. for (i in 1:5){ int_vecs[1:2, i] = c((i - 1), -(i -1)) } #if there are are three or more pulses, we need to include #integer vectors with three non-zero terms if (Npulse >= 3){ int_vecs[1:3, 6] = c(2, -1,-1) int_vecs[1:3, 7] = c(-2, 1, 1) } #if there are four or more pulses, then we need to include an #integer vector with four non-zero terms if (Npulse >= 4){ int_vecs[1:4, 8] = c(1, 1, -1,-1) } #calculates the "P" functions for each column of integer combos in #int_vec. "P" function values are independet of integer #permutations. pre_factors is a list which holds the "P"-function #values for each integer combo pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * Q_func(int_vecs[m,i]); } } #Now calculate the exponential terms which will multiply the "P"functions in the pre_factors list #post_factors = list of the exponential terms to multiply the # corresponding "P" functions in the pre_factors list post_factors = numeric(N_terms) #initialize to zero for (i in 1: N_terms){ #for each integer combo given by the columns of int_vecs... #calculates the unique permutations of the ith integer combo #int_vecs(:, i) = ith column of int_vecs matrix #perm_list = Nperms x Npulse matrix, where Nperms is the number # of unique permutations of the ith integer combo # Each row of perm_list gives a unique permutaion of the ith integer combo perm_list = uperm(int_vecs[,i]) if( i == 1){ Nperms = 1 }else{ Nperms = length(perm_list[,1]) #number of unique permutations of the ith integer combo } for (m in 1:Nperms){ #for each uniqe permutation of the ith integer combo, add the corresponding exponential to the running total of the corresponding post_factor value if(i == 1){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * (perm_list %*% z) / tau) } else { post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * (perm_list[m,] %*% z) / tau) } }#perm_list[m, ] = mth row of perm_list = mth unique permutaton of ith integer combo } val = 0 for (i in 1:N_terms){ #add together the (pre_factor * post_factor) for each integer combo val = val + pre_factors[1,i] * post_factors[i] } return(val) }else if(abs(k) == 1){ kk = abs(k) if (Npulse == 2){ N_terms = 5 }else{ N_terms = 8 } int_vecs = matrix(0,nrow=Npulse, ncol=N_terms) for (i in 1:5){ int_vecs[1:2, i] = sign(k) * c(kk + (i - 1), -(i -1)) } if (Npulse >= 3){ int_vecs[1:3, 6] = sign(k) * c(1 , 1 , -1) int_vecs[1:3, 7] = sign(k) * c(3 , -1 , -1) int_vecs[1:3, 8] = sign(k) * c(2 , -2 , 1) } pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * Q_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] +exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } val = 0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } return(val) } else if(abs(k) == 2){ kk = abs(k) if (Npulse == 2){ N_terms = 5 }else if (Npulse == 3){ N_terms = 6 }else{ N_terms = 7 } int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk + 1, -1) int_vecs[1:2, 4] = sign(k) * c(kk + 2, -2) int_vecs[1:2, 5] = sign(k) * c(kk + 3, -3) if (Npulse >= 3){ int_vecs[1:3, 6] = sign(k) *c(2, -1,1) } if (Npulse >= 4){ int_vecs[1:4, 7] = sign(k) *c(1, 1, 1,-1) } pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * Q_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) if(Npulse == 2 && i == 2){ Nperms = 1; post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list %*% z / tau) }else{ Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } } val = 0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } return(val) }else if(abs(k) == 3){ kk = abs(k) if (Npulse == 2){ N_terms = 5 }else{ N_terms = 8 } int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk + 1, -1) int_vecs[1:2, 4] = sign(k) * c(kk + 2, -2) int_vecs[1:2, 5] = sign(k) * c(kk + 3, -3) if (Npulse >= 3){ int_vecs[1:3, 6] = sign(k) *c(1, 1, 1) int_vecs[1:3, 7] = sign(k) *c(3, 1, -1) int_vecs[1:3, 8] = sign(k) *c(2, 2, -1) } pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * Q_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) if(Npulse == 3 && i == 6){ Nperms = 1 post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list %*% z / tau) }else{ Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } } val = 0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } return(val) }else if(abs(k) == 4){ kk = abs(k) if (Npulse == 2){ N_terms = 5 }else if(Npulse == 3){ N_terms = 7 }else{ N_terms = 8 } int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk -2, 2) int_vecs[1:2, 4] = sign(k) * c(kk +1, -1) int_vecs[1:2, 5] = sign(k) * c(kk + 2, -2) if (Npulse >= 3){ int_vecs[1:3, 6] = sign(k) *c(4, -1, 1) int_vecs[1:3, 7] = sign(k)*c(2, 1, 1) } if (Npulse >= 4){ int_vecs[1:4, 8] = sign(k) *c(1, 1, 1, 1) } pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * Q_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) if(Npulse == 4 && i == 8){ Nperms = 1 post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list %*% z / tau) }else if(Npulse == 2 && i == 3){ Nperms = 1 post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list %*% z / tau) } else{ Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } } val=0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } return(val) }else if(abs(k) == 5){ kk = abs(k) if (Npulse == 2){ N_terms = 5 }else{ N_terms = 7 } int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk -2, 2) int_vecs[1:2, 4] = sign(k) * c(kk + 1, -1) int_vecs[1:2, 5] = sign(k) * c(kk + 2, -2) if (Npulse >= 3){ int_vecs[1:3, 6] = sign(k) *c(2, 2, 1); int_vecs[1:3, 7] = sign(k) *c(3, 1, 1); } pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * Q_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } val=0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } return(val) }else if(abs(k) == 6){ kk = abs(k) if (Npulse == 2){ N_terms = 6 }else{ N_terms = 7 } int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk -2, 2) int_vecs[1:2, 4] = sign(k) * c(kk - 3, 3) int_vecs[1:2, 5] = sign(k) * c(kk + 1, -1) int_vecs[1:2, 6] = sign(k) * c(kk + 2, -2) if (Npulse >= 3){ int_vecs[1:3, 7] = sign(k) *c(4, 1, 1) } pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * Q_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) if(Npulse == 2 && i == 4){ Nperms = 1 post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list %*% z / tau) }else{ Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } } val=0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } return(val) }else if(abs(k) == 7){ kk = abs(k) N_terms = 6 int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk -2, 2) int_vecs[1:2, 4] = sign(k) * c(kk - 3, 3) int_vecs[1:2, 5] = sign(k) * c(kk + 1, -1) int_vecs[1:2, 6] = sign(k) * c(kk + 2, -2) pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * Q_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } val=0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } return(val) }else if(abs(k) == 8){ kk = abs(k) N_terms = 6 int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk -2, 2) int_vecs[1:2, 4] = sign(k) * c(kk + 1, -1) int_vecs[1:2, 5] = sign(k) * c(kk -3, +3) int_vecs[1:2, 6] = sign(k) * c(kk -4, +4) pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * Q_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) if(Npulse == 2 && i == 6){ Nperm = 1 post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list %*% z / tau) }else{ Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } } val=0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } return(val) }else if(abs(k) == 9){ kk = abs(k) N_terms = 5 int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk + 1, -1) int_vecs[1:2, 4] = sign(k) * c(kk -2, 2) int_vecs[1:2, 5] = sign(k) * c(kk -3, +3) pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * Q_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } val=0 for (i in 1:N_terms){ val = val + pre_factors[i] * post_factors[i] } return(val) }else if(abs(k) == 10){ kk = abs(k) N_terms = 4 int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk + 1, -1) int_vecs[1:2, 4] = sign(k) * c(kk -2, 2) pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * Q_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } val=0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } return(val) }else if(abs(k) == 11){ kk = abs(k) N_terms = 4 int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk + 1, -1) int_vecs[1:2, 4] = sign(k) * c(kk -2, 2) pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * Q_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } val=0 for (i in 1:N_terms){ val = val + pre_factors[1,i] * post_factors[i] } out = val } else{ kk = abs(k) N_terms = 3 int_vecs = matrix(0,Npulse, N_terms) int_vecs[1:2, 1] = sign(k) * c(kk + 0, 0) int_vecs[1:2, 2] = sign(k) * c(kk - 1, 1) int_vecs[1:2, 3] = sign(k) * c(kk + 1, -1) pre_factors = matrix(1, ncol=N_terms, nrow=1) for (i in 1:N_terms){ for (m in 1:Npulse){ pre_factors[1,i] = pre_factors[1,i] * Q_func(int_vecs[m,i]) } } post_factors = numeric(N_terms) for (i in 1: N_terms){ perm_list = uperm(int_vecs[,i]) Nperms = dim(perm_list)[1] for (m in 1:Nperms){ post_factors[i] = post_factors[i] + exp(-2 * pi * complex(real = 0, imaginary = 1) * perm_list[m, ] %*% z / tau) } } val=0 for (i in 1:N_terms){ val = val + pre_factors[i] * post_factors[i] } return(val) } } #this function computes the fourier sum for 1 pulse sum_1_pulse = function(z, rho, mu, tau, kmax, modes){ jmax = length(modes) #modes is the list of fourier modes, jmax = number of list elements out_val = 0 #running total for output value P_func = function(x) {rho * 1 /(log(1/(1-rho)) - 2 * pi * complex(real = 0, imaginary = 1) * x)} Q_func = function(x) {(rho / (1 - rho)) * 1 /(log(1/(1-rho)) + 2 * pi * complex(real = 0, imaginary = 1) * x)} for (k in -kmax:kmax){ pre_factor = P_func(k) post_factor = exp( -2 * pi * complex(real = 0, imaginary = 1) * k * z / tau) P_val = pre_factor * post_factor Q_val = 0 for (j in (-jmax+1):(jmax-1)){ pre_factor = Q_func(-k-j) post_factor = exp( -2 * pi * complex(real = 0, imaginary = 1) * (-k -j) * z / tau) if (j ==0){ Q_val =Q_val + pre_factor * post_factor * modes[1] / mu }else if (j <0){ Q_val =Q_val + pre_factor * post_factor * Conj(modes[-(j-1)]) / mu }else if (j>0){ Q_val =Q_val + pre_factor * post_factor * modes[j+1] / mu } } out_val = out_val + (P_val)*(Q_val) /( 1 - log(1-rho) / (mu * tau) - 2 * pi * complex(real = 0, imaginary = 1) * k /(mu * tau)); } return(Re(out_val)) } # this function computes the Fourier sum for N pulses, where the "P" and "Q" products and exponentials are computeded by the "P_vals" and "Q_vals" functions sum_N_pulse = function(z, rho, Npulse, mu, tau, kmax, modes){ jmax = length(modes) out_val = 0 #running total for output for (k in -kmax:kmax){ P_val = P_vals(z, rho, Npulse, tau, k) #compute "P" product and exponentials at this k value Q_val = 0 #running total for "Q" product and exponentials #add together "Q" products and exponentials at (k + j) value for all j emergence fourier modes for (j in (-jmax+1):(jmax-1)){ #if (abs(k+j) < kmax){ if (j ==0){ Q_val =Q_val + Q_vals(z, rho, Npulse, tau, k, j)* modes[1] / mu #zero fourier mode }else if(j <0){ Q_val = Q_val + Q_vals(z, rho, Npulse, tau, k, j) * Conj(modes[-(j-1)]) / mu #negative fourier modes }else if(j>0){ Q_val =Q_val + Q_vals(z, rho, Npulse, tau, k, j) * modes[j+1] / mu #positive fourier modes } #} } #add contribution from this k value to running output total out_val = out_val + (P_val)*(Q_val) /( 1 - Npulse * log(1-rho) / (mu * tau) - 2 * pi * complex(real= 0, imaginary = 1) * k /(mu * tau)) } out = Re(out_val) return(out) }
##optimization parameters set by user kmax = 20 #max number of dynamics fourier modes to use in calculating fourier sum (different than N_lam = max emergence fourier mode set by user for curve fitting portion of the code. I've often refered to N_lam as jmax when we've talked. Hopefully not too confusing). kmax should be an integer between 2 and 200, defualt at 20 global_opt = 0 #set to 0 if user chooses local optimum, 1 if user chooses golbal GN_DIRECT_L_RAND method, 2 if user chooses global GN_ISRES mthod Npulse = 4 #number of pulses, set by user, integer between 1 and 10 rho = .30 #percent knockdown (user set between .01 and .30, e.g. 1% to 30% knockdown) days_between = 3 #minimum number of days allowed between pulses set by user (integer bewtween 0 and 30 days)
#code to execute optimization algorithms #install.packages("nloptr") library("nloptr") #used for local cobyla optimum function and global optimum functions if(Npulse == 1){ # 1 pulse fun1 = function(x)sum_1_pulse(x,rho, mu, tau, kmax, lam_fourier) guess = tau /2 if(global_opt == 0){ #local optimum opt_out = cobyla(guess, fun1, lower = 0, upper = tau) times = opt_out$par ave_pop_fourier = opt_out$value }else if(global_opt == 1){ #global optimum directL opt_out = directL(fun1, lower = 0, upper = tau, randomized = TRUE) times = opt_out$par ave_pop_fourier = opt_out$value }else if(global_opt == 2){ #global optimum isres opt_out = nloptr(x0=guess, eval_f=fun1, lb = 0, ub = tau, eval_g_ineq = NULL, eval_g_eq = NULL, opts = list(algorithm="NLOPT_GN_ISRES",maxeval=10000)) times = opt_out$solution ave_pop_fourier = opt_out$objective } } else{ #2 or more pulses funN = function(x)sum_N_pulse(x,rho, Npulse, mu, tau, kmax, lam_fourier) #matrix and vector for inequality constraints to enforce minimum days between A_mat = matrix(0,nrow=Npulse - 1, ncol=Npulse) b_vec = (-1) * days_between * matrix(1, Npulse-1, 1) for (i in 1:(Npulse -1)){ A_mat[i,i] = 1 A_mat[i, i+ 1] = -1 } l_bound = numeric(Npulse) #column vector of zeros for pulse lower bound u_bound = tau * matrix(1,Npulse, 1) #column vector of taus for pulse upper bound guess = numeric(Npulse); #vector for initial guesses for fmincon for(i in 1:Npulse){ if(t_in[1] - m / mu > 0 ){ guess[i] = i * (t_dat[N_pts - 1] - t_dat[3]) / (Npulse + 1) + t_dat[3] }else{ guess[i] = i * (t_dat[N_pts - 2] - t_dat[2]) / (Npulse + 1) + t_dat[2] } } if(global_opt == 0){#local optimum opt_out = fmincon(guess, funN, gr= NULL, method="SQP", A = A_mat, b=b_vec, Aeq = NULL, beq = NULL, lb = l_bound, ub = u_bound) times = opt_out$par ave_pop_fourier = opt_out$value }else if(global_opt == 1){ #global optimum directL opt_out = directL(funN, lower = l_bound, upper = u_bound, randomized = TRUE) times = opt_out$par ave_pop_fourier = opt_out$value }else if(global_opt == 2){ #global optimum isres ineq = function(x){(-1)*A_mat %*%x - b_vec} opt_out = nloptr(x0=guess, eval_f=funN, lb = l_bound, ub = u_bound, eval_g_ineq = ineq, eval_g_eq = NULL, opts = list(algorithm="NLOPT_GN_ISRES",maxeval=10000)) times = opt_out$solution ave_pop_fourier = opt_out$objective } }
#code to shift times and generate plot data #shift pulse times back to original times input by user if (t_in[1]- (m/mu)>0){ pulse_times_output = times - t_dat[3] + t_in[1] }else { pulse_times_output = times - t_dat[2] + t_in[1] } #code to plot results: t_steps = 6 * tau*10 + 1 # ten time steps per day, six total seasons (need to integrate over many seasons to reach periodic population curves) t_vec = linspace(0, 6*tau, n = t_steps); #list between 0 and 6*tau, t_steps long y_fourier_controlled = numeric(t_steps) #list (row vector) for controlled population values at each time step y_fourier_uncontrolled = numeric(t_steps) #list (row vector) for uncontrolled population values at each time step #simple integrator to calculate population values for (i in 2:t_steps){ for (j in 1: N_pts - 1){ if (mod(t_vec[i-1], tau) >= t_dat[j] && mod(t_vec[i-1],tau) < t_dat[j + 1]){ y_fourier_controlled[i] = y_fourier_controlled[i-1] +(-mu * y_fourier_controlled[i-1] +lambda_dat$par[j+1] * (mod(t_vec[i-1], tau) -t_dat[j])/ delta_t_dat[j] +lambda_dat$par[j] * (t_dat[j+1] -mod(t_vec[i-1], tau)) / delta_t_dat[j])*(t_vec[i] - t_vec[i-1]); y_fourier_uncontrolled[i] = y_fourier_uncontrolled[i-1] +(-mu * y_fourier_uncontrolled[i-1] +lambda_dat$par[j+1] * (mod(t_vec[i-1], tau) -t_dat[j])/ delta_t_dat[j] +lambda_dat$par[j] * (t_dat[j+1] -mod(t_vec[i-1], tau)) / delta_t_dat[j])*(t_vec[i] - t_vec[i-1]) } } #impulses for the controlled population for (j in 1:Npulse){ if (mod(t_vec[i], tau) >= times[j] && mod(t_vec[i-1], tau) < times[j]){ y_fourier_controlled[i] = (1-rho) * y_fourier_controlled[i]; } } } pop_cont = numeric(10*tau+1) #list for controlled population vlaues, one season long pop_un_cont = numeric(10*tau+1) #list for uncontrolled population vlaues, one season long t_vec_plot = numeric(10*tau+1) #list for time values, one season long for (i in 1:(10*tau+1)){ pop_cont[i] = y_fourier_controlled[i + 10*tau*5] #take controlled population values from the integration for the final season pop_un_cont[i] = y_fourier_uncontrolled[i+ 10*tau*5] #take uncontrolled population values from the integration for the final season #shift plot times for population curves back to original times input by user if (t_in[1] - m / mu > 0) { t_vec_plot[i] = t_vec[i]-t_dat[(3)] +t_in[(1)] } else{ t_vec_plot[i] = t_vec[i] -t_dat[(2)] + t_in[(1)] } } #shift data times back to orginal times input by user if (t_in[(1)] - (m / mu) > 0){ t_dat_plot = t_dat - t_dat[(3)] + t_in[(1)] }else { t_dat_plot = t_dat - t_dat[2] + t_in[1] }
#code to generate outputs to user #install.packages("sfsmisc") library("sfsmisc") #for the integrate.xy function ave_pop_un_cont = integrate.xy(t_vec_plot, pop_un_cont)/(tau) ave_pop_cont = integrate.xy(t_vec_plot, pop_cont)/(tau) percent_reduction = (ave_pop_un_cont - ave_pop_cont) / ave_pop_un_cont accuracy_measure = (ave_pop_fourier - ave_pop_cont) / ave_pop_cont #outputs to display to user print(pulse_times_output) #times of optimal pulses in units of day of year print(ave_pop_un_cont) #average population over interval (0, tau) under uncontrolledfourier dynamics print(ave_pop_cont) #average population over interval (0, tau) under controlled fourier dynamics print(percent_reduction) #fractional reduction in average controlled population relative to uncontrolled print(accuracy_measure) #reliability measuere - if the magnitude of this quantity is larger than .05 or .1 or so, then the fourier sum may be of unrelaiable accuracy, and the user should try increasing kmax #plots to display to user plot(t_dat_plot, y_dat, ylim = c(0,1.5 * max(y_dat)), xlim=c(t_dat_plot[1],t_dat_plot[1]+tau), col="blue", main="Fitted Population Model", ylab="Mosquito population count", xlab="Day of year") lines(t_vec_plot, pop_un_cont, col="red") lines(t_vec_plot, pop_cont, col = "orange") legend("topleft",c("Data","Uncontrolled Fourier Approximation", "Controlled Fourier Approximation"),fill=c("blue","red","orange"))
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.