代码之家  ›  专栏  ›  技术社区  ›  Alejandro Andrade

使用“长”输入时RCPP功能崩溃R

  •  0
  • Alejandro Andrade  · 技术社区  · 5 年前

    我有一个C++函数,用于我正在使用的线性插值。 Rcpp 当我用不太“长”的初始向量进行插值时,函数可以很好地工作,但是当我将初始向量的大小增加三倍时,函数可以很好地从循环中工作,但是当我决定用相同的输入rstudio循环时,函数会崩溃。我看了一眼 r aborted when using rcpp R crashes when calling a Rcpp function in a loop 但我只是没有找到任何解决我的问题的方法。

    这是C++函数:

    double  InterpolacionRAWCpp(NumericVector plazos,NumericVector tasas,double plazoRequerido){
    
      double interpolacionRAW,a,p1,p2;
      int numero_plazo;
      double ayuda_plazo = plazoRequerido;
      NumericVector tn(tasas.size()+1);
      NumericVector pn(tasas.size()+1);
      tn[0] = tasas[0];
      pn[0] = 0;
      tn[Rcpp::Range(1,tn.size())] = tasas;
      pn[Rcpp::Range(1,pn.size())] = plazos;
      interpolacionRAW = 0;
      numero_plazo = tasas.size();
      if(ayuda_plazo==0){
        interpolacionRAW=tn[0];
      } else {
        for(int i =0; i<numero_plazo;++i){
          if((plazoRequerido > pn[i]) & (plazoRequerido<=pn[i+1])){
            a = pn[i+1]-pn[i];
            p1 = (pn[i+1]*tn[i+1]-pn[i]*tn[i])/a;
            p2 = (pn[i+1]*pn[i]*(tn[i]-tn[i+1]))/(a*plazoRequerido);
            interpolacionRAW=p2+p1;  
            break;
          } else if(plazoRequerido>pn[(numero_plazo-1)]){
            // Cuando el plazo es mayor al maximo plazo del vector de plazos
            // entonces se extrapola
            a=pn[(numero_plazo)]-pn[numero_plazo-1];
            p1=(pn[(numero_plazo)]*tn[(numero_plazo)]-pn[numero_plazo-1]*tn[numero_plazo-1])/a;
            interpolacionRAW=(p1*(plazoRequerido-pn[(numero_plazo)])+pn[(numero_plazo)]*tn[(numero_plazo)])/plazoRequerido;
            break;
          } else if(plazoRequerido<pn[0]){
            // Cuando el plazoRequerido es menor que el plazo minimo del vector de plazos
            // se extrapola, para atraz
            a=pn[1]-pn[0];
            p1=(pn[1]*tn[1]-pn[0]*tn[0])/a;
            interpolacionRAW=(p1*(plazoRequerido-pn[1])+pn[1]*tn[1])/plazoRequerido;
            break;
          }
    
        }
    
      }
    
      return interpolacionRAW;
    }
    

    有了这个输入,我就不会在循环函数时遇到任何问题:

    plazo2 = c(0.25,0.50,1.00,3.00,5.00,7.00,10.00,15.00)
    dato2 = c(4.147594,4.197599 ,4.403012,5.281392,6.169297,7.124895,8.699570,11.574581)
    x = NULL
    for(i in 1:10000){
      x = rbind(x,InterpolacionRAWCpp(plazo2,dato2,10))
    }
    

    但如果我改变plazo2和dato2:

    plazo1 = c(0.08333,0.16667,0.25000,0.50000,1.01389,2.02778,3.04167,4.05556,5.06944,
               6.08333,7.09722,8.11111,9.12500,10.13889,11.15278,12.16667,13.18056,14.19444,15.20833)
    dato1 = c(4.11798,4.13244,4.14501,4.19365,4.39560,4.80608,5.27216,5.71510,6.16038,
             6.62284,7.11100,7.67899,8.17816,8.68633,9.20055,9.71490,10.32713,10.94182,11.55650)
    

    rstudio会崩溃

    1 回复  |  直到 5 年前
        1
  •  1
  •   coatless    5 年前

    这是一个索引错误。 C++ 索引范围从0到 N-1 而不是 R 'S 1到N系统。

    在某种程度上,您认为这是:

    // Note vectors are n+1
    NumericVector tn(tasas.size()+1);
    NumericVector pn(tasas.size()+1);
    
    // Assign into 0
    tn[0] = tasas[0];
    pn[0] = 0;
    

    但是,下一部分有问题:

    // Here we are using n+1 but need just n. 
    tn[Rcpp::Range(1,tn.size())] = tasas;
    pn[Rcpp::Range(1,pn.size())] = plazos;
    

    将最后一部分切换到:

    // Retrieves n+1 and by subtracting 1 we stay in range.
    tn[Rcpp::Range(1,tn.size() - 1)] = tasas;
    pn[Rcpp::Range(1,pn.size() - 1)] = plazos;