I want to compute the following sequence using R, without loops, i.e. for cycles.
1 + (2/3) + ((2/3)*(4/5)) + ((2/3)*(4/5)*(6/7)) + ... + ((2/3)*(4/5)*...(20/21))
So far, I tried different approaches with a sequence as well as a while function, but could not came up with a suitable solution. Help would be highly appreciated.
We may use cumprod
v1 <- seq(2, 20, by = 2)
v2 <- seq(3, 21, by = 2)
1 + sum(cumprod(v1/v2))
[1] 4.945724
-manual calculation
1 + (2/3) + ((2/3)*(4/5)) + ((2/3)*(4/5)*(6/7)) + ((2/3)*(4/5)*(6/7) * (8/9)) + ((2/3)*(4/5)*(6/7) * (8/9) * (10/11)) + ((2/3)*(4/5)*(6/7) * (8/9) * (10/11) * (12/13)) + ((2/3)*(4/5)*(6/7) * (8/9) * (10/11) * (12/13) * (14/15)) + ((2/3)*(4/5)*(6/7) * (8/9) * (10/11) * (12/13) * (14/15) * (16/17)) + ((2/3)*(4/5)*(6/7) * (8/9) * (10/11) * (12/13) * (14/15) * (16/17) * (18/19)) + ((2/3)*(4/5)*(6/7) * (8/9) * (10/11) * (12/13) * (14/15) * (16/17) * (18/19) * (20/21))
[1] 4.945724
When I try to build a model using PKSFC, I get this message:
[... truncated]
R lists three mistakes and a half (the equations end with *_EC).
I guess I can correct the mistake, but I would like to correct them all in one pass.
I guess there are many more (maybe 15?).
The full message:
5: In sfc.check(vn_mod, fill = FALSE) : Equations
57192.4187750356 + POPAGE_1 * (0.5 * (0 - 55335.9694996733)/POPAGE_1 + 0.2 * (POPAGE - POPAGE_1)/POPAGE_1 - 0.2 * (57192.4187750356 - 0.5 * 55335.9694996733 - 0.508679781654891 * POPAGE_1)/POPAGE_1 + ACPOP_EC)
28.7269160437129 * exp(0.548725 * log(0/1.489181) + 0.704327 * log(0/37.4835480991331) - 0.247704 *
(log(28.7269160437129/37.4835480991331 * (1 + R_SCP_1)) - 0.5 *
log(1.489181) - (1 - 0.5) * log(1.52438302758911)) - 0.5 * 0 -
0.0511046682618056 + WP_EC)
1.25809781599844 * exp(0.2 * log(0/1.46079630578026) + 0.8 * log(PPX * 0/(PPX_1 * 1.1362002193817)) - 0.2 * (log(1.25809781599844) - 0.2 * log(1.46079630578026) - (1 - 0.2) * log(PPX_1 * 1.1362002193817)) -
0.00325177611673638 * (T - 2016) * (T <= 2016) - 0.0576138445722962 + PM_EC)
1.30468806319261 * exp(0.7 * log(0/1.46079630578026) + 0.3 * log(PPX * 0/(PPX_1 * 1.1362002193817)) - 0.2 * (log(1.30468806319261) - 0.7 * log(1.46079630578026) - (1 - 0.7) * log(PPX_1 * 1.1362002193817)) -
0.0033333860060119 * (T - 201 [... truncated]
I wrote a function, which returns a function based on certain properties.
The problem is that I had to use "paste", which makes the returned object a string. Here an example of the returned object:
the_problem <- "beta['v_p'] * 0.1 * ((3.99 * exp(-0.144 * time)) +
(4.78 * exp(-0.0111 * time))) + 0.1 * beta['ktrans_1'] * (3.99 * (exp(-
beta['kep_1']* time) - exp(- 0.144 * time)) * (0.144 -
beta['kep_1'])**(-1) + (4.78 * (exp(- beta['kep_1'] * time)- exp(-
0.0111 * time)) * (0.0111 - beta['kep_1'])**(-1)))"
I would like to manipulate the object "the_problem" to make it usable as function. Something like:
dcemri_func <- function(beta){
return(get.rid.of.string(the_problem))}
I already tried "as.function", but this does not work.
Any ideas?
Thanks and best whishes,
Chris
You could try using eval(parse(text = ..)), i.e.:
the_problem <- paste0('function(beta) ', the_problem)
dcemri_func <- eval(parse(text = the_problem))
I am currently trying to find an equivalent for the following equation:
vec_res = inverse(VM) * (q * (VM * vec_input) * conjugate(q))
where VM is a standard view matrix , q is a normalized quaternion, and vec_input a vector.
In the form:
vec_res = A * vec_input;
or
vec_res = q' * vec_input * conjugate(q');
From https://molecularmusings.wordpress.com/2013/05/24/a-faster-quaternion-vector-multiplication/ I am already calculating
vec_res = inverse(VM) * q * VM * vec_input * conjugate(q)
as
pN = (VM * vec_input);
vec3 tempVec = 2.0 * cross(q.xyz, pN);
pN = pN + q.w * tempVec + cross(q.xyz, tempVec);
pN = inverse(VM) * pN;
My question is, do I have the right to rewrite the equation like this ?
vec_res = (inverse(VM) * conversion_to_matrix(q) * VM) * vec_input
Where conversion_to_matrix is the rotation matrix calculated as explained in: http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/
If no, what is the math to be used behind ?
Note that multiplying your vector with
inverse(VM) * conversion_to_matrix(q) * VM
is not the same as multiplying it with
conversion_to_matrix(q)
since matrix multiplication is not commutative. So you really have to compute the entire matrix given in the first formula above.
vec_res = (inverse(VM) * conversion_to_matrix(q) * VM) * vec_input
Is perfectly valid.
The problem is...
inverse(VM) * conversion_to_matrix(q) * VM
is NOT equal to
conversion_to_matrix(q)
Therefore you have to keep the original equation in its entirety.
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=", ")