有没有一种方法可以在Rust中创建一个闭包来计算具有随机系数的n次多项式?

ufj5ltwl  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(81)

所以我们的想法是有一个函数,它返回一个具有随机系数的n次闭包。这对于比较根查找方法可能很有用,例如,我们可以自动创建要计算的函数。将任何操作转换为闭包的返回将是一个更强大的资源,所以如果有什么方法可以做到这一点,请告诉我。
代码应该如下所示:

use rand::Rng;
fn create_func(n: u8) -> impl Fn(f64) -> f64 { 
    let mut cst = vec![];
    for _ in 0..n{
        cst.push(rand::thread_rng().gen_range(0..=20)  as f64);
        // establish the coefficients by randomly generating them
    }
    move |x| cst[0]*x + cst[1]*x.powf(1.) + /*...*/ cst[n- 1]*x.powf(n as f64)
}

所以很明显,最后一部分并不是一种有效的方式来表达我们想要返回的闭包的其余部分,但我希望你能理解。

eqqqjvef

eqqqjvef1#

你在寻找一个和,所以把你的序列变成一个迭代器,它将被求和。

move |x| {
    cst.iter()
        .zip(0..=n as i32)
        .map(|(&c, exp)| c * x.powi(exp))
        .sum()
}

对于每一项,需要cstiter)中的元素及其指数(zip)。您可以从这些项(map)中一次构造一个项,然后将所有项相加(sum)。
我还修正了你的术语数量(你的术语没有 x^0),并使用了sample_iter,这比每次都调用thread_rng要快。因为所有的指数都是整数,所以我换成了powi

pub fn create_func(n: u8) -> impl Fn(f64) -> f64 {
    let cst: Vec<f64> = rand::thread_rng()
        .sample_iter(rand::distributions::Uniform::new_inclusive(0, 20))
        .map(|n| n as f64)
        .take(n as usize + 1)
        .collect();

    move |x| {
        cst.iter()
            .zip(0..=n as i32)
            .map(|(&c, exp)| c * x.powi(exp))
            .sum()
    }
}
xcitsw88

xcitsw882#

多项式的其他表达方式如下:

P_fold_n(x) = (…(((x + a_1) * x + a_2) * x + a_3)…) * x + a_n

P_map_n(x) = (x + a_1) * (x + a_2) * (x + a_3) … * (x + a_n)

这导致以下实现:

fn poly_via_fold(coeffs: Vec<f64>) -> impl Fn(f64) -> f64 {
    move |x: f64| coeffs.iter().fold(1.0, |res, a| res * x + a)
}

fn poly_via_map(coeffs: Vec<f64>) -> impl Fn(f64) -> f64 {
    move |x: f64| coeffs.iter().map(|a| x + a).product()
}

相关问题