Используйте непосредственно функции cpp_ extradistr в коде C ++ [дубликат]

В то время как обещания и обратные вызовы хорошо работают во многих ситуациях, боль в задней части выражает нечто вроде:

if (!name) {
  name = async1();
}
async2(name);

. В итоге вы пройдете через async1; проверьте, не определено ли name или нет, и соответственно вызовите обратный вызов.

async1(name, callback) {
  if (name)
    callback(name)
  else {
    doSomething(callback)
  }
}

async1(name, async2)

Хотя в в порядке хорошо , это раздражает, когда у вас много подобных случаев и обработка ошибок.

Fibers помогает в решении проблемы.

var Fiber = require('fibers')

function async1(container) {
  var current = Fiber.current
  var result
  doSomething(function(name) {
    result = name
    fiber.run()
  })
  Fiber.yield()
  return result
}

Fiber(function() {
  var name
  if (!name) {
    name = async1()
  }
  async2(name)
  // Make any number of async calls from here
}

Вы можете проверить проект здесь .

12
задан baptiste 9 December 2013 в 17:28
поделиться

3 ответа

К сожалению, cubature не отправляет заголовки в inst/include, поэтому вы должны брать их у них и делать что-то вроде этого в своем коде:

typedef void (*integrand) (unsigned ndim, const double *x, void *,
           unsigned fdim, double *fval);

int adapt_integrate(
    unsigned fdim, integrand f, void *fdata,
    unsigned dim, const double *xmin, const double *xmax, 
    unsigned maxEval, double reqAbsError, double reqRelError, 
    double *val, double *err)
{
    typedef int (*Fun)(unsigned,integrand,void*,unsigned,
        const double*,const double*, unsigned, double, double, double*, double*) ;
    Fun fun = (Fun) R_GetCCallable( "cubature", "adapt_integrate" ) ;           
    return fun(fdim,f,fdata,dim,xmin,xmax,maxEval,reqAbsError, reqRelError,val,err); 
}

Это может быть хорошей идеей чтобы обсудить с сопровождающим cubature, что он отправляет объявления в inst/include, так что вам нужно будет использовать LinkingTo.

6
ответ дан Romain Francois 25 August 2018 в 17:15
поделиться

Не видел этого вопроса раньше, и похоже, что @Romain обратился к нему.

Для полноты рабочий пример того, как это сделать, когда все стороны играют, предоставляется xts и RcppXts. В xts мы делаем это (около десяти функций) в файле (source) inst/include/xtsAPI.h:

SEXP attribute_hidden xtsLag(SEXP x, SEXP k, SEXP pad) {     
    static SEXP(*fun)(SEXP,SEXP,SEXP) = NULL;         
    if (fun == NULL)                                  
        fun = (SEXP(*)(SEXP,SEXP,SEXP)) R_GetCCallable("xts","lagXts");   
    return fun(x, k, pad);                               
}  

вместе с обычной работой R_registerRoutines и R_RegisterCCallable.

В RcppXts это подбирается (в модуле Rcpp) как

function("xtsLag", 
         &xtsLag,    
         List::create(Named("x"), Named("k"), Named("pad")),   
         "Extract the coredata from xts object");

, который работает очень хорошо. Кто-то сделал мне выговор, чтобы написать xts сторону более компактно (поскольку if NULL является ложным), который я получу ... в конце концов.

4
ответ дан Dirk Eddelbuettel 25 August 2018 в 17:15
поделиться

Этот вопрос сейчас три года, но я хочу отметить, что многомерная интеграция с Rcpp может быть проще теперь, когда доступна библиотека RcppNumerical: https://github.com/yixuan/RcppNumerical

Подпрограммы для вычислений интегралов основаны на кубинском пакете Томаса Хана и также доступны в библиотеке R2Cuba на CRAN, поэтому, если вы можете согласиться с использованием кубинских процедур над функцией adaptIntegrate() из Cubature, этот пакет может представлять интерес.

1
ответ дан user31313 25 August 2018 в 17:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: