gpt4 book ai didi

rust - 将浮点和从 Python 重写为 Rust

转载 作者:行者123 更新时间:2023-11-29 08:05:23 25 4
gpt4 key购买 nike

我一直在尝试重写下面的代码,以便在最小化舍入误差的同时对 float 求和,但我发现在 Rust 中很难做到。任何建议将不胜感激。我附上我的无效 Rust 尝试

def msum(iterable):
"Full precision summation using multiple floats for intermediate values"
# Rounded x+y stored in hi with the round-off stored in lo. Together
# hi+lo are exactly equal to x+y. The inner loop applies hi/lo summation
# to each partial so that the list of partial sums remains exact.
# Depends on IEEE-754 arithmetic guarantees. See proof of correctness at:
#www-2.cs.cmu.edu/afs/cs/project/quake/public/papers/robust-arithmetic.ps

partials = [] # sorted, non-overlapping partial sums
for x in iterable:
i = 0
for y in partials:
if abs(x) < abs(y):
x, y = y, x
hi = x + y
lo = y - (hi - x)
if lo:
partials[i] = lo
i += 1
x = hi
partials[i:] = [x]
return sum(partials, 0.0)

下面的代码是我目前在 Rust 中的代码,但它还不能工作

fn inexact_sum(v: &Vec<f64>) -> f64 {
let mut partials: Vec<f64> = vec![];
for x in v {

let mut i: usize = 0;
let mut hi: f64;
let mut lo: f64;

for y in partials.clone().iter() {
hi = x + y;
lo = if x.abs() < y.abs() {
y - (hi - x)
} else {
x - (hi - y)
};
if lo != 0.0_f64 {
partials[i] = lo;
i += 1;
}
let x = hi;
println!("x = {}, y = {}", x, y);
}
partials.truncate(i);
partials.push(hi);
}
partials.iter().fold(0.0_f64, |a, b| a + b)
}

编辑:仔细想想,确实,编译器给我的错误 error: use of possibly uninitialized variable: `hi` 确实很有用。我应该多注意它。关键是第一次循环根本没有执行,所以 hi 没有被初始化。因此,如果我将 partials.push(hi); 更改为 partials.push(*x);,代码会编译并运行,但不会给出正确的答案。

最佳答案

这是您要找的吗?我认为您并不是要克隆 partials 数组,而是发现您需要这样做才能满足借用检查器的要求;如果您尝试使用代码:

for y in partials.iter() {
...
partials[i] = lo;

借用检查员会提示:

<anon>:13:17: 13:25 error: cannot borrow `partials` as mutable because it is also borrowed as immutable [E0502]

我通过在数组中使用索引来解决这个问题:

for j in 0..partials.len() {
let mut y = partials[j];

然后你就不会在外循环中每次都克隆整个数组!由于 partials 数组可以在遍历它的同时进行修改,因此首先进行克隆意味着您将得到 y 的旧值而不是新值(如果它已经被复制)已修改。

use std::mem;

fn msum(v: &[f64]) -> f64 {
let mut partials: Vec<f64> = vec![];
for x in v {
let mut x = *x;
let mut i = 0;
for j in 0..partials.len() {
let mut y = partials[j];
if x.abs() < y.abs() { mem::swap(&mut x, &mut y) }
let hi = x + y;
let lo = y - (hi - x);
if lo != 0.0 {
partials[i] = lo;
i += 1;
}
x = hi;
}
partials.truncate(i);
partials.push(x);
}
partials.iter().fold(0., |a, b| a + b)
}

fn main() {
let v = vec![1.234, 1e16, 1.234, -1e16];
println!("{}",msum(&v));
}

Playpen

关于rust - 将浮点和从 Python 重写为 Rust,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36018019/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com