Help translating this C++ code please!

Hi - first post here, so I hope this question is okay, and isn't outside the scope of this forum. I'm trying to translate this to Rust (CppLowess/Lowess.h at master · hroest/CppLowess · GitHub). It's been going okay I think so far. Then I came across this snippet:

size_t m1 = n / 2;

// Use nth element to find element m1, which produces a partially sorted
// vector. This means we can get element m2 by looking for the maximum in the
// remainder.

typename ContainerType::iterator it_m1 = resid_weights.begin() + m1;

std::nth_element(resid_weights.begin(), it_m1, resid_weights.end());
      
typename ContainerType::iterator it_m2 = std::max_element(resid_weights.begin(), it_m1);

Which uses a combination of nth_element & max_element. The variables which are important downstream are it_m1 and it_m2. I'm tying myself in knots trying to understand this. I think Rust iterators must be pretty different to C++ ones...

Any help greatly appreciated.
M

In order to add an arbitrary integer to an iterator, it essentially means that it must be random-access. You should probably translate this code into Rust using slices, not iterators.

I don't think the Rust standard library provides an implementation of nth_element.

You can use slice::select_nth_unstable (or one of it's variants) as a replacement for cpp's std::nth_element

Edit: note that cpp iterators are quite different from Rust iterators. In this case the cpp iterator is required to be random access, which makes it roughly equivalent to a slice.

1 Like

Thanks all. slice::select_nth_unstable can only be used on non-floats. Are there f32/f64 implementations. Can I do one by hand?

That really depends on what you want to do with NaN. By default, NaN is neither greater, smaller nor equal to any float, IIRC. That's why f32 and f64 only implement PartialOrd and not Ord, the latter is required for the slice method.

2 Likes

…and so if you are sure your input doesn't contain any NaN values, you can use e.g. ordered_float::NotNan to wrap your values and provide a total ordering.

1 Like

You can also use slice::select_nth_unstable_by and provide your own compare function.

5 Likes