我在Rust中实现了一个从M个不同的正态分布中采样N次的函数,因为我的R代码太慢了。它也是并行的。下面是纯Rust代码:
use rand_distr::{Normal, Distribution};
use rayon::prelude::*;
fn rust_rprednorm(n: i32, means: Vec<f64>, sds: Vec<f64>) -> Vec<Vec<f64>> {
let mut preds = vec![vec![0.0; n as usize]; means.len()];
preds.par_iter_mut().enumerate().for_each(|(i, e)| {
let mut rng = rand::thread_rng();
(0..n).into_iter().for_each(|j| {
let normal = Normal::new(means[i], sds[i]).unwrap();
e[j as usize] = normal.sample(&mut rng);
})
});
preds
}
我正尝试使用rextendr库从R调用它,代码在我使用source()导入的utils.R文件中:
code <- r"(
use rand_distr::{Normal, Distribution};
use rayon::prelude::*;
#[extendr]
fn rust_rprednorm(n: i32, means: Vec<f64>, sds: Vec<f64>) -> Vec<Vec<f64>> {
let mut preds = vec![vec![0.0; n as usize]; means.len()];
preds.par_iter_mut().enumerate().for_each(|(i, e)| {
let mut rng = rand::thread_rng();
(0..n).into_iter().for_each(|j| {
let normal = Normal::new(means[i], sds[i]).unwrap();
e[j as usize] = normal.sample(&mut rng);
})
});
preds
}
)"
rust_source(code = code, dependencies = list(`rand` = "0.8.5", `rand_distr` ="0.4.3", `rayon` = "1.6.1"))
错误为:
Error in `invoke_cargo()`:
! Rust code could not be compiled successfully. Aborting.
✖ error[E0277]: the trait bound `Robj: From<Vec<Vec<f64>>>` is not satisfied
--> src\lib.rs:6:5
|
6 | #[extendr]
| ^^^^^^^^^^ the trait `From<Vec<Vec<f64>>>` is not implemented for `Robj`
|
= help: the following other types implement trait `From<T>`:
<Robj as From<&'a [T]>>
<Robj as From<&Altrep>>
<Robj as From<&Primitive>>
<Robj as From<&Robj>>
<Robj as From<&Vec<T>>>
<Robj as From<&extendr_api::Complexes>>
<Robj as From<&extendr_api::Doubles>>
<Robj as From<&extendr_api::Environment>>
and 71 others
= note: this error originates in the attribute macro `extendr` (in Nightly builds, run with -Z macro-backtrace for more info)
✖ error: aborting due to previous error
Traceback:
1. source("inla_predictive_distribution_utils.R")
2. withVisible(eval(ei, envir))
3. eval(ei, envir)
4. eval(ei, envir)
5. rust_source(code = code, dependencies = list(rand = "0.8.5",
. rand_distr = "0.4.3", rayon = "1.6.1"))
6. invoke_cargo(toolchain = toolchain, specific_target = specific_target,
. dir = dir, profile = profile, quiet = quiet, use_rtools = use_rtools)
7. check_cargo_output(compilation_result, message_buffer, tty_has_colors(),
. quiet)
8. ui_throw("Rust code could not be compiled successfully. Aborting.",
. error_messages, call = call, glue_open = "{<{", glue_close = "}>}")
9. withr::with_options(list(warning.length = message_limit_bytes),
. rlang::abort(message, class = "rextendr_error", call = call))
10. force(code)
11. rlang::abort(message, class = "rextendr_error", call = call)
12. signal_abort(cnd, .file)
我认为嵌套向量会被支持,因为常规向量是,但它似乎不是,我需要为Robj实现这个特性吗,或者有其他方法吗?我也不确定这是否是从R调用Rust代码的推荐方法。
1条答案
按热度按时间ljsrvy3e1#
您不能返回类似
Vec<Vec<T>>
的内容,因为R
并不真正理解这些内容。Rmatrix
类型就是用于此目的的ndarray
的支持有限,ndarray
也转换为R矩阵Vec<T>
元素的List