recursive series mupad - recursion

I am trying to find the sum from n=1 to n=infinity of the following series:
A(n)=T/(n+1)*{a1*T^2*A(n-3)/((n-1)*n) + a2*T*A(n-2)/n + a3*A(n-1)}
with
A(-1)=A(0)=0
A(1)=T*a1/2
using mupad. Is it possible?
I tried the following code:
A := proc(n)
begin
if(n<=0) then return(0) end_if:
if(n=1) then return(a_1*T/2) end_if:
return((T/(n+1))*(a_1*T^2*A(n-3)/((n-1)*n)
+a_2*T*A(n-2)/n
+a_3*A(n-1)))
end_proc:
which works fine for single elements of series A, however when i try to find even the partial sum for n=1..2:
sum(A(n),n=1..2)
mupad returns an error:
Error: Can't evaluate to boolean [_leequal];
during evaluation of 'A'
Is there a simpler approach to this problem?

Related

Why does using paste in for loop return error?

I have a few problems concerning the same topic.
(1) I am trying to loop over:
premium1999 <- as.data.frame(coef(summary(data1999_mod))[c(19:44), 1])
for 10 years, in which I wrote:
for (year in seq(1999,2008)) {
paste0('premium',year) <- as.data.frame(coef(summary(paste0('data',year,'_mod')))[c(19:44), 1])
}
Note:
for data1999_mod is regression results that I want extract some of its estimators as a dataframe vector.
The coef(summary(data1999_mod)) looks like this:
#A matrix: ... of type dbl
Estimate Std. Error t value Pr(>|t|)
age 0.0388573570 2.196772e-03 17.6883885 3.362887e-6
age_sqr -0.0003065876 2.790296e-05 -10.9876373 5.826926e-28
relation 0.0724525759 9.168118e-03 7.9026659 2.950318e-15
sex -0.1348453659 8.970138e-03 -15.0326966 1.201003e-50
marital 0.0782049161 8.928773e-03 8.7587533 2.217825e-18
reg 0.1691004469 1.132230e-02 14.9351735 5.082589e-50
...
However, it returns Error: $ operator is invalid for atomic vectors, even if I did not use $ operator here.
(2) Also,
I want to create a column 'year' containing repeated values of the associated year and am trying to loop over this:
premium1999$year <- 1999
In which I wrote:
for (i in seq(1999,2008)) {
assign(paste0('premium',i)[['year']], i)
}
In this case, it returns Error in paste0("premium", i)[["year"]]: subscript out of bounds
(3) Moreover, I'd like to repeat some rows and loop over:
premium1999 <- rbind(premium1999, premium1999[rep(1, 2),])
for 10 years again and I wrote:
for (year in seq(1999,2008)) {
paste0('premium',year) <- rbind(paste0('premium',year), paste0('premium',year)[rep(1, 2),])
}
This time it returns Error in paste0("premium", year)[rep(1, 2), ]: incorrect number of dimensions
I also tried to loop over a few other similar things but I always get Error.
Each code works fine individually.
I could not find what I did wrong. Any help or suggestions would be very highly appreciated.
The problem with the code is that the paste0() function returns the character and not calling the object that is having the name as this character. For example, paste0('data',year,'_mod') returns a character vector of length 1, i.e., "data1999_mod" and not calling the object data1999_mod.
For easy understanding, there is huge a difference between, "data1999_mod"["Estimate"] and data1999_mod["Estimate"]. Subsetting as data frame merely by paste0() function returns the former, however, the expected output will be given by the latter only. That is why you are getting, Error: $ operator is invalid for atomic vectors.
The same error is found in all of your codes. On order to call the object by the output of a paste0() function, we need to enclose is by get().
As, you have not supplied the reproducible sample, I couldn't test it. However, you can try running these.
#(1)
for (year in seq(1999,2008)) {
paste0('premium',year) <- as.data.frame(coef(summary(get(paste0('data',year,'_mod'))))[c(19:44), 1])
}
#(2)
for (i in seq(1999,2008)) {
assign(get(paste0('premium',i))[['year']], i)
}
#(3)
for (year in seq(1999,2008)) {
paste0('premium',year) <- rbind(get(paste0('premium',year)), get(paste0('premium',year))[rep(1, 2),])
}

Having trouble creating error statements when creating function

I am creating a function in R for calculating compound interest using the equation - F=P\left(1+\frac{i}{100t}\right)^{ty}.
I need to create error messages if any of P, i, t, or y arguments are not numeric or negative, and an error if i is out of the range 0-100.
When I try to run the code i get the error message:
Error: unexpected ',' in:
" stop("Argument 'P','i','t' and 'y' must be numeric")
if(P,"
and am unsure how to fix it or what I have done wrong. The code so far is:
compound <- function(P,i,t=12,y,plotit=FALSE,...){
# 1. Check arguments and throw errors here using 'if' statements
if(!is.numeric(P,i,t,y)){
stop("Argument 'P','i','t' and 'y' must be numeric")
if(P,i,t,y<0){
stop("Argument 'P','i','t' and 'y' must be non-negative")
if(i<0||i>100){
stop("'i' must be within the range 0-100 percent")
}
}
}
if(plotit==TRUE){
# 2. Do plot if necessary here according to 'plotit' argument
y <- floor(y)
f <- P*((1+(i/100*t))^t*y)
for(i in length(y)){
plot(f, type = 's')
}
}
else {
final.result <- f
# Calculate final result here
return(final.result)
}
}
Any help on how to improve the code would be great!
The problem is that you are passing four arguments to is.numeric(P,i,t,y). It can take only one.
if(!all(sapply(list(P,i,t,y), is.numeric)))
That will check if all arguments are numeric.
A similar problem occurs with if(P,i,t,y<0), so use:
if(!all(sapply(list(P,i,t,y), function(x) x >= 0)))
Additionally, you have nested these if statements, which means the second and the third will not be evaluated. Move them out of your first if statement.

User-defined function producing 'Could not find function' error

My dataset test[[1]] can be found here.
I'm defining a function and using it in a for loop in the following code. The function is supposed to concatenate strings such as (test[[1]], '$', names(test[[1]])[1])) before converting them into an R variable. So in this example, these strings go in and out comes test[[1]]$V1.
I then iterate the function over the variables in test[[1]].
Unfortunately, I keep getting this error: Error in stvar(test[[1]], j) <- NULL : could not find function "stvar<-".
stvar <- function(df,num) {
eval(parse(text=paste(deparse(substitute(df)),'$',names(df)[num],sep='')))
}
for (j in 1:length(names(test[[1]]))){
if (trimws(as.character(stvar(test[[1]],j)[1]))=="Div" &
grepl("^M",stvar(test[[1]],j)[3])==0) {
stvar(test[[1]],j) <- NULL
}
}
Also, not sure if this is important, but the for-loop finds columns containing certain characteristics (first observation == "Div", third observation doesn't start with 'M') and removes matching columns.
Is there a way I can make the loop recognize my function?

R: invalid 'times' argument calculating CRPS

I'm trying to calculate crps using the verification package in R. The data appears to read in ok, but I get an error when trying to compute the CRPS itself: "invalid 'times' argument", however all values are real, no negative values and I'm testing for nan/na values and ignoring those. Having searched around I can't find any solution which explains why I'm getting this error. I'm reading the data in from netcdf files into larger arrays, and then computing CRPS for each grid cell in those arrays.
Any help would be greatly appreciated!
The relevant snipped from the code I'm using is:
##for each grid cell, get obs (wbarray) and 25 ensemble members of forecast eps (fcstarray)
for(x in 1:3600){
for(y in 1:1500){
obs=wbarray[x,y]
eps=fcstarray[x,y,1:25]
if(!is.na(obs)){
print(obs)
print(eps)
print("calculating CRPS - real value found")
crpsfcst=(crpsDecomposition(obs,eps)$CRPS)
CRPSfcst[x,y,w]=crpsfcst}}}
(w is specified in an earlier loop)
And the output I get:
obs: 0.3850737
eps: 0.3382506 0.3466184 0.3508921 0.3428135 0.3416993 0.3423528 0.3307764
0.3372431 0.3394377 0.3398165 0.3414395 0.3531360 0.3319155 0.3453161
0.3362813 0.3449474 0.3340050 0.3278898 0.3380596 0.3379150 0.3429202
0.3467927 0.3419354 0.3472489 0.3550797
"calculating CRPS - real value found"
Error in rep(0, nObs * (nMember +1)) : invalid 'times' argument
Calls: crpsDecomposition
Execution halted
If you type crpsDecomposition on your R command prompt you'll get the source code for the function. The first few lines show:
function (obs, eps)
{
nMember = dim(eps)[2]
nObs <- length(obs)
Since your eps data object appears to be (from your output) a one-dimensional vector, the second element of its dimension is going to be NULL, which sets nMember to NULL. Thus nObs*(nMember + 1) gets evaluated to 0. I imagine you simply need to re-examine what form eps should take because it would appear that it needs to be a matrix where each column corresponds to a different "member" (whatever that means in this context).

What is difference between subset function and filter function in R?

When I do these two functions in R, one returns error, but one works well. Why? I think both functions return same thing.
impute[1,]$steps <- filter(steps_per_interval,
interval==impute[1,]$interval)[,2]
Error: invalid subscript type 'integer'
impute[1,]$steps <- subset(steps_per_interval,
interval==impute[1,]$interval)[,2]
Not sure if I'm correct, but seems like inside filter you can't make a reference combining $ and [] in the same expression as in interval==impute[1,]$interval. Instead you could try:
x < -which(colnames(impute)=="interval")
library(dplyr)
impute[1,]$steps <- filter(steps_per_interval,
interval==impute[1,x])[,2]

Resources