For loop inside a function to create m number of functions - r

Suppose I have the following function and output:
library('pracma')
xlag= c(1,3,5,8,12,16,19,20,22,24)
f1 <- function(beta){
xlag[1]*exp(beta[1] * 1)/(exp(beta[1] * 1)+exp(beta[1] * 2)+exp(beta[1] * 3)) +
xlag[2]*exp(beta[1] * 2)/(exp(beta[1] * 1)+exp(beta[1] * 2)+exp(beta[1] * 3)) +
xlag[3]*exp(beta[1] * 3)/(exp(beta[1] * 1)+exp(beta[1] * 2)+exp(beta[1] * 3))
}
pracma::jacobian(f1,c(1))
[,1]
[1,] 0.8488091
I wrote a few for loops in the function so I can extend the model for any value s.
h <-function(beta){
s = 1:3
xlag= 1:9
n <-c()
for (i in s) {
n[i] <- exp(beta[1] * s[i])
}
sal <-sum(n)
z <-c()
for (i in s) {
z[i] <- xlag[i]*exp(beta[1] * s[i])/sal
}
sum(z)
}
pracma::jacobian(h,c(1))
[,1]
[1,] 0.8488091
Now I would like to write f for xlag[1:3], xlag[4:6] xlag[7:9].
Such that the Jacobian becomes a matrix with 1 column and 3 rows. Where the first entry is the one specified above. And the second entry is:
f2 <- function(beta){
xlag[4]*exp(beta[4] * 1)/(exp(beta[1] * 1)+exp(beta[1] * 2)+exp(beta[1] * 3)) +
xlag[5]*exp(beta[5] * 2)/(exp(beta[1] * 1)+exp(beta[1] * 2)+exp(beta[1] * 3)) +
xlag[6]*exp(beta[6] * 3)/(exp(beta[1] * 1)+exp(beta[1] * 2)+exp(beta[1] * 3))
}
pracma::jacobian(f2,c(1))
[,1]
[1,] 1.697618
The third entry:
f3 <- function(beta){
xlag[7]*exp(beta[4] * 1)/(exp(beta[1] * 1)+exp(beta[1] * 2)+exp(beta[1] * 3)) +
xlag[8]*exp(beta[5] * 2)/(exp(beta[1] * 1)+exp(beta[1] * 2)+exp(beta[1] * 3)) +
xlag[9]*exp(beta[6] * 3)/(exp(beta[1] * 1)+exp(beta[1] * 2)+exp(beta[1] * 3))
}
pracma::jacobian(f3,c(1))
[,1]
[1,] 0.706992
So I would like h to output:
[,1]
[1,] 0.8488091
[2,] 1.697618
[3,] 0.706992
The jacobian function is structured as follow
library('pracma')
jacobian(f, x0, heps = .Machine$double.eps^(1/3), ...)
f: m functions of n variables.
x0: Numeric vector of length n.
heps: This is h in the derivative formula.
jacobian(): Computes the derivative of each function f_j by variable x_i separately, taking the discrete step h.
So I need 3 functions f1,f2,f3 of one variable. Yielding a matrix of 1 column and 3 rows.
Could anyone help me rewrite h such that I get the desired output?

I have found the solution.
h <-function(beta){
s = 1:3
xlag #total set of xlag variables
u =1:(length(xlag)-length(s)) #basis for loop
n <-c()
for (i in s) {
n[i] <- exp(beta[1] * s[i]) #nominator expo almon
}
sal <-sum(n) #denominator expo almon
z <-c()
for (i in s) {
z[i] <- exp(beta[1] * s[i])/sal #expoalmon
}
final <-c()
for (i in u) {
final[i] <- sum(xlag[(i):(i+2)]*z[1:3])
}
final
}
pracma::jacobian(h,c(1))

Related

plotting Hamid Naderi Yeganehs parrot using ggplot

I am a) new to stackoverflow and b) an advanced beginner to R ;-)
i saw some bird artworks of Yeganeh with the associated functions in the web Drawing Birds in Flight With Mathematics and wanted to reproduce them in R to experiment a bit with colouring and so on.
However, while this one yielded a quite good result:
k <- 1:9830
X <- function(k) {
sin(pi * k / 20000) ^ 12 *
(0.5 * cos(31 * pi * k / 10000) ^ 16 *
sin(6 * pi * k / 10000) + (1 / 6 * sin(31 * pi * k / 10000)) ^ 20) +
3 * k / 20000 + cos(31 * pi * k / 10000) ^ 6 *
sin((pi / 2) * ((k - 10000) / 10000) ^ 7 - pi / 5)
}
Y <- function(k) {
-9 / 4 * cos(31 * pi * k / 10000) ^ 6 *
cos(pi / 2 * ((k - 10000) / 10000) ^ 7 - pi / 5) *
(2 / 3 + (sin(pi * k / 20000) * sin(3 * pi * k / 20000)) ^ 6) +
3 / 4 * cos(3 * pi * ((k - 10000) / 100000)) ^ 10 *
cos(9 * pi * ((k - 10000) / 100000)) ^ 10 *
cos(36 * pi * ((k - 10000) / 100000)) ^ 14 +
7 / 10 * ((k - 10000) / 10000) ^ 2
}
R <- function(k) {
sin(pi * k / 20000) ^ 10 *
(1 / 4 * cos(31 * pi * k / 10000 + 25 * pi / 32) ^ 20 +
1 / 20 * cos(31 * pi * k / 10000) ^ 2) +
1 / 30 * (3 / 2 - cos(62 * pi * k / 10000) ^ 2)
}
bird <- data.frame(x = X(k), y = Y(k), r = R(k))
library(tidyverse)
library(ggforce)
q <- ggplot() +
geom_circle(aes(x0 = x, y0 = y, r = r),
data = bird,
n = 30) +
coord_fixed() +
theme_void()
the following code yielded some weird result which should basically be related to the difference in the function. (x-A(k))+(y-B(k))=(R(k)) for the parrot below, whlie the bird above "simply" consisted of the k-th circle (X(k), Y(k)) and the radius of the k-th circle R(k)
k <- -10000:10000
A <- function(k) {
(3*k/20000)+(cos(37*pi*k/10000))*sin((k/10000)*(3*pi/5))+(9/7)*(cos(37*pi*k/10000))*(cos(pi*k/20000))*sin(pi*k/10000)
}
B <- function(k) {
(-5/4)*(cos(37*pi*k/10000))*cos((k/10000)*(3*pi/5))*(1+3*(cos(pi*k/20000)*cos(3*pi*k/20000)))+(2/3)*(cos(3*pi*k/200000)*cos(9*pi*k/200000)*cos(9*pi*k/100000))
}
R <- function(k) {
(1/32)+(1/15)*(sin(37*pi*k/10000))*((sin(pi*k/10000))+(3/2)*(cos(pi*k/20000)))
}
parrot <- data.frame(a = A(k), b = B(k), r = R(k))
q <- ggplot() +
geom_circle(aes(x0 = a, y0 = b, r = r),
data = parrot,
n=30) +
coord_fixed() +
theme_void()
q
Any help would be very much appreciated. Cartesian coords already applied as [explained here] (https://www.wikiwand.com/en/Hamid_Naderi_Yeganeh). From the visual point of view, it seems like the function is plotted properly but the "view" on it needs to be changed...
Thanks in advance!

Calculating double integral with gamma incomplete function in R

I need to calculate a double integral on two variables (B0 and B1) in R.
Till now, nothing complicated with the int2 function.
But, my function to integrate includes gamma incomplete function (gammainc in R ) !
The following error message appears :
Error in gammainc(1/eta, lambda * exp(B0 + B1 * z_arm) * tmax^eta) :
Arguments must be of length 1; function is not vectorized.
Any advice to help me ?
tmax = 5
Sig = matrix ( c(0.2, 0, 0, 0.4) , ncol = 2 )
Mu = matrix ( c(1, 0) , ncol = 1 )
eta = 0.5
lambda = 0.8
z_arm = c(rep(0.5,10), rep(1,15))
to.integrate = function(B0, B1)
{
first.int = 1/eta *(lambda * exp(B0 + B1 * z_arm))^(-1/eta)* gammainc(1/eta, lambda * exp(B0 + B1 * z_arm)*tmax^eta)['lowinc']
B = matrix(c(B0, B1), ncol=1)
multi.norm = 1 / (2 * pi * det(Sig)^(1/2)) * exp (- 0.5 * t( B - Mu ) * solve(Sig) * ( B - Mu ) )
return (first.int * multi.norm)
}
int2(to.integrate , a=c(-Inf,-Inf), b=c(Inf,Inf), eps=1.0e-6, max=16, d=5)
Thanks for any help!

How to avoid NaN in an e function?

I am trying to solve these equations for q1 and q2. However, the output is giving me "NaN". Does anyone have an idea how to avoid those?
k2<-2
k1<-2
a<- 20
b<- -0.03
w <- 1.1
model <- function(q) {
pi1 <- -exp(-a*(w*(100*q[1]-0.5*q[1]^2-0.5*q[1]*q[2])-k1)*(-a*(w*(100-q[1]-0.5*q[2])-k1)))
pi2 <- -exp(-a*(w*(100*q[2]-0.5*q[2]^2-0.5*q[1]*q[2])-k2)*(-a*(w*(100-q[2]-0.5*q[1])-k2)))
c(pi1 = pi1, pi2 = pi2)
}
ss1 <- rootSolve::multiroot(f = model, start = c(1, 1))
ss1
Thanks in advance!!!
I have been able to find the roots with the following code :
model <- function(q, bool_Print = FALSE)
{
k2 <- 2
k1 <- 2
a <- 20
b <- -0.03
w <- 1.1
pi1 <- exp( -a * (w * (100 * q[1] - 0.5 * q[1] ^ 2 - 0.5 * q[1] * q[2]) - k1) * (-a * (w * (100 - q[1] - 0.5 * q[2]) - k1)))
pi2 <- exp( -a * (w * (100 * q[2] - 0.5 *q[2] ^2 - 0.5 * q[1] * q[2]) - k2) * (-a * (w * (100 - q[2] - 0.5 * q[1]) - k2)))
val <- pi1 ^ 2 + pi2 ^ 2
names(val) <- NULL
if(bool_Print == TRUE)
{
print("pi1")
print(pi1)
print("pi2")
print(pi2)
print("Val")
}
if(is.na(val) | is.nan(val) | is.infinite(val))
{
return(10 ^ 30)
}else
{
return(val)
}
}
library(DEoptim)
obj_DEoptim <- DEoptim(fn = model, lower = rep(-1000, 2), upper = rep(1000, 2))
model(q = obj_DEoptim$optim$bestmem, bool_Print = TRUE)
[1] "pi1"
par1
0
[1] "pi2"
par2
0
[1] "Val"
[1] 0

Evaluating one variable with a list

I have the following code:
nth <- expression(((1/p)*a0/2)+sum(((1/p)*a*cos(i*pi*x/p)))+sum((1/p)*b*sin(i*pi*x/p)))
nth <- as.expression(gsub('pi',pi,nth))
nth <- as.expression(gsub('p',p,nth))
nth <- as.expression(gsub('a0',a0,nth))
nth <- as.expression(gsub('a',a,nth))
nth <- as.expression(gsub('b',b,nth))
this results to the expression:
"((1/1) * 1.26424111790395/2) + sum(((1/1) * 0.251688909862584 * cos(i * 3.14159265358979 * x/1))) + sum((1/1) * -1.03501509824516e-16 * sin(i * 3.14159265358979 * x/1))"
What I want to do next is to evaluate i with a list (eg. i = 1:3) without evaluating x. So what I want to get is something like:
"((1/1) * 1.26424111790395/2) + sum(((1/1) * 0.251688909862584 * cos(1 * 3.14159265358979 * x/1)), ((1/1) * 0.251688909862584 * cos(2 * 3.14159265358979 * x/1)), ((1/1) * 0.251688909862584 * cos(3 * 3.14159265358979 * x/1))) + sum(((1/1) * 0.251688909862584 * sin(1 * 3.14159265358979 * x/1)), ((1/1) * 0.251688909862584 * sin(2 * 3.14159265358979 * x/1)), ((1/1) * 0.251688909862584 * sin(3 * 3.14159265358979 * x/1)))"
How can I do this? Thanks.
Why not try this. You will see that I wrapped the values you needed in a loop and put all output in a new "finished" dataframe that will be updated as you roll through the loop. You can specify how many i's there are and change the expression as you wish:
# Define the initial variables that might be changed here
var_1 <- 3.14159265358979 # This referred to pi in your initial expression
var_2 <- 1 # This referred to p in your initial expression
var_3 <- 1.26424111790395 # This refers to a0 in your initial expression
var_4 <- 0.251688909862584 # This refers to a in your initial expression
var_5 <- -1.03501509824516e-16 # This refers to b in your initial expression
n <- 3 # This is the number of equations that will be run through
# Create an empty dataframe to hold the outputted expressions
finished = c() # Empty data frame
# Create an array holding values from 1 to the number of n's that will be run through
cycle <- c(1:n)
# Convert cycle to a matrix
cycle <- as.matrix(cycle)
# The variable we will be changing is i ... Create the initial loop
for (i in 1:3 ) {
nth <- expression(((1/p)*a0/2)+sum(((1/p)*a*cos(i*pi*x/p)))+sum((1/p)*b*sin(i*pi*x/p))) # Write the expression to be changed
# Substitute in all the relevant values. Note that this is made to be more explicity
nth <- as.expression(gsub('pi',var_1,nth))
nth <- as.expression(gsub('p',var_2,nth))
nth <- as.expression(gsub('a0',var_3,nth))
nth <- as.expression(gsub('a',var_4,nth))
nth <- as.expression(gsub('b',var_5,nth))
# I will also, for each value, substitue in relevant value from the cycle array
# This will change the i values for you
i_index <- cycle[i,1]
i_index <- as.character(i_index)
nth <- as.expression(gsub('i',i_index,nth)) # Append the nth equation
# I will then bind this solution into the finished data frame to hold all solutions
finished[i] = nth
}
This is the output that was generated after running the code:
expression("((1/1) * 1.26424111790395/2) + sum(((1/1) * 0.251688909862584 * cos(1 * 3.14159265358979 * x/1))) + sum((1/1) * -1.03501509824516e-16 * s1n(1 * 3.14159265358979 * x/1))",
"((1/1) * 1.26424111790395/2) + sum(((1/1) * 0.251688909862584 * cos(2 * 3.14159265358979 * x/1))) + sum((1/1) * -1.03501509824516e-16 * s2n(2 * 3.14159265358979 * x/1))",
"((1/1) * 1.26424111790395/2) + sum(((1/1) * 0.251688909862584 * cos(3 * 3.14159265358979 * x/1))) + sum((1/1) * -1.03501509824516e-16 * s3n(3 * 3.14159265358979 * x/1))")
This should get you going. You were definitely on the right track with gsub.
Notice that j in the original expression is being replaced with 1, 2, and 3, respectively. I went with j because gsub with i interferes with sin and pi. Hope it helps...
> expres <- "(((1/p)*a0/2)+sum(((1/p)*a*cos(j*pi*x/p)))+sum((1/p)*b*sin(j*pi*x/p)))"
> noquote(sapply(1:3, function(j){
GS <- gsub("j", as.numeric(j), expres)
paste0("expression(", GS, ")")
}))
[1] expression((((1/p)*a0/2)+sum(((1/p)*a*cos(1*pi*x/p)))+sum((1/p)*b*sin(1*pi*x/p))))
[2] expression((((1/p)*a0/2)+sum(((1/p)*a*cos(2*pi*x/p)))+sum((1/p)*b*sin(2*pi*x/p))))
[3] expression((((1/p)*a0/2)+sum(((1/p)*a*cos(3*pi*x/p)))+sum((1/p)*b*sin(3*pi*x/p))))
Another possible solution is to use substitute
g = function(i){
env = list(pi=pi, p=1, a0=1.26424111790395, a=0.251688909862584, b=-1.03501509824516e-16, i=i)
as.character(as.expression(substitute(((1/p)*a0/2)+sum(((1/p)*a*cos(i*pi*x/p)))+sum((1/p)*b*sin(i*pi*x/p)), env)))
}
paste(lapply(1:3, g), collapse=", ")

Using lanczos low pass filter in R program

I am wondering if there is any package which allows us to use the Lanczos filter. I found other filters such as butterworth but I am looking for Lanczos low pass filter.
How different is Lanczos filter from butterworth filter ? Any suggestions or hints is appreciated.
Thanks.
Using the web I find this MATLAB implementation.
If you skipped the first part(arguments check), it looks simple to write its R equivalent.
# Cf - Cut-off frequency (default: half Nyquist)
# M - Number of coefficients (default: 100)
lanczos_filter_coef <- function(Cf,M=100){
lowpass_cosine_filter_coef <- function(Cf,M)
coef <- Cf*c(1,sin(pi*seq(M)*Cf)/(pi*seq(M)*Cf))
hkcs <- lowpass_cosine_filter_coef(Cf,M)
sigma <- c(1,sin(pi*seq(M)/M)/(pi*seq(M)/M))
hkB <- hkcs*sigma
hkA <- -hkB
hkA[1] <- hkA[1]+1
coef <- cbind(hkB, hkA)
coef
}
To test it for example:
dT <- 1
Nf <- 1/(2*dT)
Cf <- Nf/2
Cf <- Cf/Nf
lanczos_filter_coef(Cf,5)
hkB hkA
[1,] 5.000000e-01 5.000000e-01
[2,] 2.977755e-01 -2.977755e-01
[3,] 1.475072e-17 -1.475072e-17
[4,] -5.353454e-02 5.353454e-02
[5,] -4.558222e-18 4.558222e-18
[6,] 2.481571e-18 -2.481571e-18
PS I don't know very well MATLAB(used it many years ago), so I I used this link For the R/MATLAB analogy. I hope that someone with more R/MATLAB/Scilab knowledge can test my code.
I used the method provided in this link https://www.atmos.umd.edu/~ekalnay/syllabi/AOSC630/METO630ClassNotes13.pdf and wrote this function:
`
lanczos_weights<-function(window=101,sampl_rate=1,type="lowpass",low_freq=1/100,high_freq=1/10){
low_freq=sampl_rate*low_freq
high_freq=sampl_rate*high_freq
if (type=="lowpass"){
order = ((window - 1) %/% 2 ) + 1
nwts = 2 * order + 1
fc=low_freq
w = seq(0,0,length=nwts)
n = nwts %/% 2
w[n+1] = 2 * fc
k = seq(1, n-1)
sigma = sin(pi * k / n) * n / (pi * k)
firstfactor = sin(2 *pi * fc * k) / (pi * k)
w[n:2] = firstfactor * sigma
w[(n+2):(length(w)-1)] = firstfactor * sigma
w=w[-c(1,length(w))]}
else if (type=="highpass"){
order = ((window - 1) %/% 2 ) + 1
nwts = 2 * order + 1
fc=high_freq
w = seq(0,0,length=nwts)
n = nwts %/% 2
w[n+1] = 2 * fc
k = seq(1, n-1)
sigma = sin(pi * k / n) * n / (pi * k)
firstfactor = sin(2 *pi * fc * k) / (pi * k)
w[n:2] = firstfactor * sigma
w[(n+2):(length(w)-1)] = firstfactor * sigma
w=w[-c(1,length(w))]
w=-w
w[order]=1-2*fc }
else if (type=="bandpass"){
order = ((window - 1) %/% 2 ) + 1
nwts = 2 * order + 1
fc=low_freq
w = seq(0,0,length=nwts)
n = nwts %/% 2
w[n+1] = 2 * fc
k = seq(1, n-1)
sigma = sin(pi * k / n) * n / (pi * k)
firstfactor = sin(2 *pi * fc * k) / (pi * k)
w[n:2] = firstfactor * sigma
w[(n+2):(length(w)-1)] = firstfactor * sigma
w1=w[-c(1,length(w))]
order = ((window - 1) %/% 2 ) + 1
nwts = 2 * order + 1
fc=high_freq
w = seq(0,0,length=nwts)
n = nwts %/% 2
w[n+1] = 2 * fc
k = seq(1, n-1)
sigma = sin(pi * k / n) * n / (pi * k)
firstfactor = sin(2 *pi * fc * k) / (pi * k)
w[n:2] = firstfactor * sigma
w[(n+2):(length(w)-1)] = firstfactor * sigma
w2=w[-c(1,length(w))]
w=w2-w1}
else {print("Please specify a valid filter type: either 'lowpass', 'highpass' or 'bandpass'")}
return(w)}
`
#### the inputs are:
#### window: Filter length=number of weights. Corresponds to the total number of points to be lost. Should be odd: window=2N-1. The formula for N is taken from Poan et al. (2013)
#### sampl_rate: sampling rate=number of observation per time unit. ( eg: if time unit is one day, hourly data have sampl_rate=1/24)
#### type= one of "lowpass", "highpass" and "bandpass"
#### low_freq: the lowest frequency
#### high_freq: the highest frequency
I have compared my weights to those obtained using NCL filwgts_lanczos and they are exactly the same.

Resources