Hi I have made the sample code again. Could you please guide how to use vectorization for variables whose next value depends on the previous one? w = NULL for(j in 1:1000) { z = NULL x = rnorm(2000) z[1] = x[1] for(i in 2:2000) { z[i] = x[i]+5*z[i-1] if(z[i]>4 | z[i]<1) { w[j]=i } else { w[j] = 0 } } } On Sun, Jan 31, 2021 at 10:01 AM David Winsemius <dwinsemius at comcast.net> wrote:> > On 1/30/21 8:26 PM, Shaami wrote: > > Hi > > I have very large dependent nested for loops that are quite expensive > > computationally. It takes weeks and does not end to give me results. > Could > > anyone please guide how could I use apply function or any other > suggestion > > for such big and dependent loops in R? A sample code is as follows. > > > > w = NULL > > for(j in 1:1000) > > { > > x = rnorm(2000) > > z = x[1] > > for(i in 2:2000) > > { > > z = x[i]+5*z[i-1] > > I'm guessing you meant to type: > > z[i] <- x[i]+5*z[i-1] > > > if(z>4 | z<1) { > > And more guesses (in the absence of any sort of problem description) > that you really wanted: > > > if(z[i]>4 | z[i]<1) { .... > > > > w[j]=i > > break > > } else { > > w[j] = 0 > > } > > } > > } > > > Are you sure you need a for-loop? Seems like you could have done this > with a couple of vectorized operations. And the `break` looked entirely > superfluous. > > > > > Thank you > > > > [[alternative HTML version deleted]] > > > > ______________________________________________ > > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > > https://stat.ethz.ch/mailman/listinfo/r-help > > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > > and provide commented, minimal, self-contained, reproducible code. >[[alternative HTML version deleted]]
> On Jan 30, 2021, at 9:32 PM, Shaami <nzshaam at gmail.com> wrote: > > Hi > I have made the sample code again. Could you please guide how to use > vectorization for variables whose next value depends on the previous one? >Glad to help. First, it could help you to trace your code. I suspect that the results are not at all what you want and tracing would help you see that. I suggest running this revision and printing out x, z, and w. #+begin_src R w = NULL for(j in 1:2) { z = NULL x = rnorm(10) z[1] = x[1] for(i in 2:10) { z[i] = x[i]+5*z[i-1] if(z[i]>4 | z[i]<1) { w[j]=i } else { w[j] = 0 } } } #+end_src You should be able to see that the value of w can easily be obtained outside of the `i' loop. -- If inspecting those results did not make you go back and rethink your approach, try writing the expression for z[n] = x[n] + ... + k * x[1] If you are not good with algebra write out each of z[1], z[2], z[3] and z[4] in terms of x[1:4] and then look at what you have. Perhaps the value of `k' will surprise you. In any case, if the code is truly what you intended, you only need x[1:25] to get z[n] to double precision for any n. So, Also, you will hardly ever be able to compute the value of z[n] for n > 450. If these last two statements are puzzling, see https://en.wikipedia.org/wiki/Floating-point_arithmetic HTH, Chuck> w = NULL > > for(j in 1:1000) > > { > > z = NULL > > x = rnorm(2000) > > z[1] = x[1] > > for(i in 2:2000) > > { > > z[i] = x[i]+5*z[i-1] > > if(z[i]>4 | z[i]<1) { > > w[j]=i > > } else { > > w[j] = 0 > > } > > } > > } >
On 1/31/21 1:26 PM, Berry, Charles wrote:> >> On Jan 30, 2021, at 9:32 PM, Shaami <nzshaam at gmail.com> wrote: >> >> Hi >> I have made the sample code again. Could you please guide how to use >> vectorization for variables whose next value depends on the previous one? >>I agree with Charles that I suspect your results are not what you expect. You should try using cat or print to output intermediate results to the console. I would suggest you limit your examination to a more manageable length, say the first 10 results while you are working out your logic. After you have the logic debugged, you can move on to long sequences. This is my suggestion for a more compact solution (at least for the inner loop calculation): set.seed(123) x <- rnorm(2000) z <- Reduce( function(x,y) { sum(y+5*x) }, x, accumulate=TRUE) w<- numeric(2000) w <-? (1:2000)[ z >4 | z < 1 ]? # In your version the w values get overwritten and end up all being 2000 I would also advise making a natural language statement of the problem and goals. I'm thinking that you may be missing certain aspects of the underying problem. -- David.> > Glad to help. > > First, it could help you to trace your code. I suspect that the results are not at all what you want and tracing would help you see that. > > I suggest running this revision and printing out x, z, and w. > > #+begin_src R > w = NULL > for(j in 1:2) > { > z = NULL > x = rnorm(10) > z[1] = x[1] > for(i in 2:10) > { > z[i] = x[i]+5*z[i-1] > if(z[i]>4 | z[i]<1) { > w[j]=i > } else { > w[j] = 0 > } > } > } > #+end_src > > > You should be able to see that the value of w can easily be obtained outside of the `i' loop. >