根据应用于最后一个生成数字的方程生成序列增加的向量

时间:2018-12-29 12:36:57

标签: r

我想产生一个从1开始并在900处停止的向量,其中每个增加都是基于取最后生成的数字并加1,然后将其乘以1.55;然后将其四舍五入到最接近的数字。

该顺序应为:

First number:  1 (i.e., start at 1)

Second number: 3 (i.e., (1+1)*1.55)

Third number:  6 (i.e., (3+1)*1.55)

我尝试过:

 x0=1
 seq(x0, 600, (+1*1.55))

3 个答案:

答案 0 :(得分:3)

使用while循环的一种不太聪明的方法

stop = 900
new_num = 1
num = 1

while(new_num < stop) {
  new_num = round((new_num + 1) * 1.55)
  num = c(num, new_num)
}

head(num,-1)
# [1]   1   3   6  11  19  31  50  79 124 194 302 470 730

答案 1 :(得分:2)

减少解决方案

这是使用Reduce

的解决方案
# framework
x0       <- 1
bound    <- 900
r        <- 1.55
estimate <- round(log(bound, r))
# iterations and filtering 
vec      <- Reduce(f = function(y,x) round((1+y)*r), x = 1:estimate, 
                   init = x0, accumulate = TRUE)
vec      <- vec[vec <= bound]
# result
[1]   1   3   6  11  19  31  50  79 124 194 302 470 730   

注释

  • 如评论中所述,要使整数必须使用round;floor;ceil;etc.,我选择了round。但是“真”值不是整数。
  • 我计算出estimate中使用的Reduce,以便对结果的大小有一个大概的了解-当然可以做得更好。

Rcpp解决方案

这里是使用Rcpp包的解决方案(因此,该功能以c++编写并“转换”为R函数)。这里的函数使用一个while循环,所以@RonakShah的解决方案几乎是用c++编写的。

C ++文件

#include <Rcpp.h>

using namespace Rcpp;

// [[Rcpp::export]]
NumericVector nateCpp(int init, int bound) {
  int current   = init;
  int outLength = 1;
  NumericVector out(outLength);
  out[0] = current;
  while ((int) round((1+current)*1.55) <= bound) {
    current = (int) round((1+current)*1.55);
    out.insert(out.length(), current);
  }
  return out;
}

R文件

# sourcing the file to have the function 
Rcpp::sourceCpp('MyCppFile.cpp')
nateCpp(1,900)
[1]   1   3   6  11  19  31  50  79 124 194 302 470 730

基准化

以下是基准数据:

Unit: microseconds
             expr    min     lq      mean median     uq      max neval cld
   ronak(1, 10^5) 34.644 38.656 56.628269 40.844 52.878 25973.41 1e+05   c
    nate(1, 10^5) 36.103 40.844 57.294825 43.032 53.243 26714.79 1e+05   c
  darren(1, 10^5) 29.903 33.550 46.599951 35.374 41.209 12248.98 1e+05  b 
 nateCpp(1, 10^5)  2.553  4.012  6.578349  4.741  5.471 10963.14 1e+05 a 

毫不奇怪,涉及c++的解决方案是迄今为止最快的。对于仅R解决方案,

  • @DarrenTsai的递归最快(尽管应谨慎使用递归,否则可能会出现诸如嵌套表达式过多的问题-在这种情况下,随着数字的快速增长应该很好),随后是
  • @RonakShah和我的职能。

功能

ronak <- function(x0,stop) {
  new_num = 1
  num = 1

  while(new_num < stop) {
    new_num = round((new_num + 1) * 1.55)
    num = c(num, new_num)
  }

  head(num,-1)
}
nate <- function(x0, bound) {
  r        <- 1.55
  estimate <- round(log(bound, r)) 
  vec      <- Reduce(f = function(y,x) round((1+y)*r), x = 1:estimate, init = x0, accumulate = TRUE)
  vec      <- vec[vec <= bound]
  vec
}
darren <- function(start, end){
  n <- length(start) ; last <- start[n]
  if(last >= end)
    return(start[-n])
  else
    darren(c(start, round((last + 1) * 1.55)), end)
}

答案 2 :(得分:2)

一个递归解决方案:

document.onload = function(e){ 
   let mainNav = document.getElementById('js-menu');
   let navBarToggle = document.getElementById('js-navbar-toggle');

   navBarToggle.addEventListener('click', function () {
      mainNav.classList.toggle('active');
   });
}