Most efficient way to fill a vector from back to front - vector

I am trying to populate a vector with a sequence of values. In order to calculate the first value I need to calculate the second value, which depends on the third value etc etc.
let mut bxs = Vec::with_capacity(n);
for x in info {
let b = match bxs.last() {
Some(bx) => union(&bx, &x.bbox),
None => x.bbox.clone(),
};
bxs.push(b);
}
bxs.reverse();
Currently I just fill the vector front to back using v.push(x) and then reverse the vector using v.reverse(). Is there a way to do this in a single pass?

Is there a way to do this in a single pass?
If you don't mind adapting the vector, it's relatively easy.
struct RevVec<T> {
data: Vec<T>,
}
impl<T> RevVec<T> {
fn push_front(&mut self, t: T) { self.data.push(t); }
}
impl<T> Index<usize> for RevVec<T> {
type Output = T;
fn index(&self, index: usize) -> &T {
&self.data[self.len() - index - 1]
}
}
impl<T> IndexMut<usize> for RevVec<T> {
fn index_mut(&mut self, index: usize) -> &mut T {
let len = self.len();
&mut self.data[len - index - 1]
}
}

The solution using unsafe is below. The unsafe version is slightly more than 2x as fast as the safe version using reverse(). The idea is to use Vec::with_capacity(usize) to allocate the vector, then use ptr::write(dst: *mut T, src: T) to write the elements into the vector back to front. offset(self, count: isize) -> *const T is used to calculate the offset into the vector.
extern crate time;
use std::fmt::Debug;
use std::ptr;
use time::PreciseTime;
fn scanl<T, F>(u : &Vec<T>, f : F) -> Vec<T>
where T : Clone,
F : Fn(&T, &T) -> T {
let mut v = Vec::with_capacity(u.len());
for x in u.iter().rev() {
let b = match v.last() {
None => (*x).clone(),
Some(y) => f(x, &y),
};
v.push(b);
}
v.reverse();
return v;
}
fn unsafe_scanl<T, F>(u : &Vec<T> , f : F) -> Vec<T>
where T : Clone + Debug,
F : Fn(&T, &T) -> T {
unsafe {
let mut v : Vec<T> = Vec::with_capacity(u.len());
let cap = v.capacity();
let p = v.as_mut_ptr();
match u.last() {
None => return v,
Some(x) => ptr::write(p.offset((u.len()-1) as isize), x.clone()),
};
for i in (0..u.len()-1).rev() {
ptr::write(p.offset(i as isize), f(v.get_unchecked(i+1), u.get_unchecked(i)));
}
Vec::set_len(&mut v, cap);
return v;
}
}
pub fn bench_scanl() {
let lo : u64 = 0;
let hi : u64 = 1000000;
let v : Vec<u64> = (lo..hi).collect();
let start = PreciseTime::now();
let u = scanl(&v, |x, y| x + y);
let end= PreciseTime::now();
println!("{:?}\n in {}", u.len(), start.to(end));
let start2 = PreciseTime::now();
let u = unsafe_scanl(&v, |x, y| x + y);
let end2 = PreciseTime::now();
println!("2){:?}\n in {}", u.len(), start2.to(end2));
}

Related

Why can't this struct method add an element to a vector through a mutable reference?

I have been trying to implement SHA256 as a practice, but I stumbled upon a behavior that I do not fully understand.
I start with a Vec<u8>, where I place the data to be hashed. Then, I pass a mutable reference to the hash function, where it adds the SHA2 padding. The problem is that when the push function is reached within the hash function, it does not add a thing.
I determined this behavior using the debugger, since the program does not crashes, just hangs in the while.
use std::fmt;
struct Sha256 {
state: [u32; 8],
k: [u32; 64]
}
impl fmt::Display for Sha256 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:x?}{:x?}{:x?}{:x?}{:x?}{:x?}{:x?}{:x?}",
self.state[0],self.state[1],self.state[2],self.state[3],
self.state[4],self.state[5],self.state[6],self.state[7]
)
}
}
impl Sha256 {
pub fn new() -> Sha256 {
Sha256 {
state: [
0x6a09e667,
0xbb67ae85,
0x3c6ef372,
0xa54ff53a,
0x510e527f,
0x9b05688c,
0x1f83d9ab,
0x5be0cd19
],
k: [
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
]
}
}
pub fn process_block(&mut self, data: &[u8]) {
let mut w = [0u32; 64];
for (i, &d) in data.iter().enumerate() {
let byte = i % 4;
let word = i / 4;
w[word] |= (d as u32) << ((8*(3-byte)) as u32);
}
println!("{:?}", w);
for i in 16..64 {
let s0 = w[i-15].rotate_right(7) ^ w[i-15].rotate_right(18) ^ w[i-15].rotate_right(3);
let s1 = w[i-2].rotate_right(17) ^ w[i-2].rotate_right(19) ^ w[i-2].rotate_right(10);
w[i] = w[i-16].wrapping_add(s0).wrapping_add(w[i-7]).wrapping_add(s1);
}
let mut a = self.state[0];
let mut b = self.state[1];
let mut c = self.state[2];
let mut d = self.state[3];
let mut e = self.state[4];
let mut f = self.state[5];
let mut g = self.state[6];
let mut h = self.state[7];
for i in 0..64 {
let s1 = e.rotate_right(6) ^ e.rotate_right(11) ^ e.rotate_right(25);
let ch = (e & f) ^((!e) & g);
let t1 = h.wrapping_add(s1).wrapping_add(ch).wrapping_add(self.k[i]).wrapping_add(w[i]);
let s0 = a.rotate_right(2) ^ a.rotate_right(13) ^ a.rotate_right(22);
let maj = (a & b)^(a & c)^(b & c);
let t2 = s0.wrapping_add(maj);
h = g;
g = f;
f = e;
e = d.wrapping_add(t1);
d = c;
c = b;
b = a;
a = t1.wrapping_add(t2);
}
self.state[0] = self.state[0].wrapping_add(a);
self.state[1] = self.state[1].wrapping_add(b);
self.state[2] = self.state[2].wrapping_add(c);
self.state[3] = self.state[3].wrapping_add(d);
self.state[4] = self.state[4].wrapping_add(e);
self.state[5] = self.state[5].wrapping_add(f);
self.state[6] = self.state[6].wrapping_add(g);
self.state[7] = self.state[7].wrapping_add(h);
}
pub fn hash(&mut self, v: &mut Vec<u8>) {
v.push(0x80);
while (v.len()%64) < 56 {
v.push(0x00);
}
let size = v.len() as u64;
let mut s_idx = 0;
while s_idx < 8 {
let byte = ((size >> (8*(7-s_idx))) & 0xffu64 ) as u8;
s_idx += 1;
v.push(byte);
}
println!("{:?}", v);
for i in 0..(v.len()/64) {
self.process_block(&v[i*64..(i+1)*64]);
}
}
}
fn main() {
let mut th = Sha256::new();
let mut v = Vec::<u8>::new();
// Sha256::hash(&mut th, &mut v); // This not work
th.hash(&mut v); // Neither do this
println!("{}", th);
}
If I create another function I am able to push data within the function, like this:
fn add_elem(v: &mut Vec<u8>) {
v.push(10);
}
fn main() {
let mut th = Sha256::new();
let mut v = Vec::<u8>::new();
add_elem(&mut v);
th.hash(&mut v);
println!("{}", th);
}
I don't know what I am missing here, because the reference is the same, but it works sometimes and others not.
I am using the Rust 1.59 stable version for Linux and Windows (tested in both systems).
It seems to be a debugger error in this function, since the vector does in fact grow, but it cannot be seen by calling p v in the GDB console.

Borrow error when attempting recursion on HashMap, where each value needs a reference to the map

I'm currently have an issue regarding Rust's borrowing policy.
I have a HashMap of structs 'Value', each which contains a list of keys to other Values in HashMap. I am attempting to recursively call a function on these Values which requires a reference to the HashMap.
use std::collections::HashMap;
struct Value {
val: f64,
prevs: Vec<usize>,
sum: f64,
}
impl Value {
pub fn new(i: usize) -> Value {
let mut res = Value {
val: 0.1,
prevs: Vec::new(),
sum: 0.0,
};
for j in 0..i {
res.prevs.push(j);
}
res
}
pub fn evaluate(&mut self, pool: &mut HashMap<usize, Value>) -> f64 {
self.sum = self.val;
for i in &self.prevs {
let prev = pool.get_mut(i).unwrap();
self.sum += prev.evaluate(pool);
}
self.sum
}
}
fn main() {
let mut hm: HashMap<usize, Value> = HashMap::new();
for i in 0..10 {
hm.insert(i, Value::new(i));
}
println!("{}", hm.get(&9).unwrap().evaluate(&mut hm));
}
Error:
error[E0499]: cannot borrow `*pool` as mutable more than once at a time
--> src/lib.rs:25:39
|
24 | let prev = pool.get_mut(i).unwrap();
| --------------- first mutable borrow occurs here
25 | self.sum += prev.evaluate(pool);
| -------- ^^^^ second mutable borrow occurs here
| |
| first borrow later used by call
Playground
Context
I'm attempting to calculate the output of a neural network (usually done via feedforward) by starting from the output, and recursively evaluating each node, as a weighted sum of the nodes connected to it, with an unpredictable topology. This requires each node having a list of input_nodes, which are keys to a node pool HashMap.
Below is a sample with a few variants:
Non-performant and probably deadlock-prone but compiling version using Arc<Mutex>
High-performance version using Vec and split_at_mut
Highly unsafe, UB and "against-all-good-practices" version using Vec and pointers. At least evaluates to the same number, wanted to add for performance comparison.
#![feature(test)]
extern crate test;
use std::{collections::HashMap, sync::{Arc, Mutex}};
#[derive(Debug)]
struct Value {
val: f64,
prevs: Vec<usize>,
sum: f64,
}
impl Value {
pub fn new(i: usize) -> Value {
let mut res = Value {
val: 0.1,
prevs: Vec::new(),
sum: 0.0,
};
for j in 0..i {
res.prevs.push(j);
}
res
}
pub fn evaluate(&mut self, pool: &mut HashMap<usize, Arc<Mutex<Value>>>) -> f64 {
self.sum = self.val;
for i in &self.prevs {
let val = pool.get_mut(i).unwrap().clone();
self.sum += val.lock().unwrap().evaluate(pool);
}
self.sum
}
pub fn evaluate_split(&mut self, pool: &mut [Value]) -> f64 {
self.sum = self.val;
for i in &self.prevs {
let (hm, val) = pool.split_at_mut(*i);
self.sum += val[0].evaluate_split(hm);
}
self.sum
}
// OBS! Don't do this, horribly unsafe and wrong
pub unsafe fn evaluate_unsafe(&mut self, pool: *const Value, pool_len: usize) -> f64 {
let pool = std::slice::from_raw_parts_mut(pool as *mut Value, pool_len);
self.sum = self.val;
for i in &self.prevs {
let (pool_ptr, pool_len) = (pool.as_ptr(), pool.len());
self.sum += pool[*i].evaluate_unsafe(pool_ptr, pool_len);
}
self.sum
}
}
fn main() {
// arcmutex
let mut hm: HashMap<usize, Arc<Mutex<Value>>> = HashMap::new();
for i in 0..10 {
hm.insert(i, Arc::new(Mutex::new(Value::new(i))));
}
let val = hm.get(&9).unwrap().clone();
assert_eq!(val.lock().unwrap().evaluate(&mut hm), 51.2);
// split vec
let mut hm = (0..10).map(|v| {
Value::new(v)
}).collect::<Vec<_>>();
let (hm, val) = hm.split_at_mut(9);
assert_eq!((hm.len(), val.len()), (9, 1));
assert_eq!(val[0].evaluate_split(hm), 51.2);
}
#[cfg(test)]
mod tests {
use test::bench;
use super::*;
#[bench]
fn bench_arc_mutex(b: &mut bench::Bencher) {
let mut hm: HashMap<usize, Arc<Mutex<Value>>> = HashMap::new();
for i in 0..10 {
hm.insert(i, Arc::new(Mutex::new(Value::new(i))));
}
b.iter(|| {
let val = hm.get(&9).unwrap().clone();
assert_eq!(val.lock().unwrap().evaluate(&mut hm), 51.2);
});
}
#[bench]
fn bench_split(b: &mut bench::Bencher) {
let mut hm = (0..10).map(|v| {
Value::new(v)
}).collect::<Vec<_>>();
b.iter(|| {
let (hm, val) = hm.split_at_mut(9);
assert_eq!(val[0].evaluate_split(hm), 51.2);
});
}
#[bench]
fn bench_unsafe(b: &mut bench::Bencher) {
let mut hm = (0..10).map(|v| {
Value::new(v)
}).collect::<Vec<_>>();
b.iter(|| {
// OBS! Don't do this, horribly unsafe and wrong
let (hm_ptr, hm_len) = (hm.as_ptr(), hm.len());
let val = &mut hm[9];
assert_eq!(unsafe { val.evaluate_unsafe(hm_ptr, hm_len) }, 51.2);
});
}
}
cargo bench results to:
running 3 tests
test tests::bench_arc_mutex ... bench: 13,249 ns/iter (+/- 367)
test tests::bench_split ... bench: 1,974 ns/iter (+/- 70)
test tests::bench_unsafe ... bench: 1,989 ns/iter (+/- 62)
Also, have a look at https://rust-unofficial.github.io/too-many-lists/index.html

How do I calculate a multiple factorial using num_bigint in Rust?

I am trying to calculate a factorial of a factorial in Rust using the Num-BigInt library. I've gotten to the point where I can calculate a factorial:
use num_bigint::BigUint;
use num_traits::{One, Zero, FromPrimitive};
fn factorial(n: usize) -> BigUint {
let mut f: BigUint = One::one();
for i in 1..(n+1) {
let bu: BigUint = FromPrimitive::from_usize(i).unwrap();
f = f * bu;
}
f
}
pub fn main() {
println!("Starting calculation...");
println!("{}", factorial(5));
}
I want to do a double factorial, like:
pub fn main() {
println!("Starting calculation...");
println!("{}", factorial(factorial(5)));
}
However, this throws the following error because the data types are different:
error[E0308]: mismatched types
--> src/main.rs:16:30
|
16 | println!("{}", factorial(factorial(5)));
| ^^^^^^^^^^^^ expected `usize`, found struct `BigUint`
How can I repeat this function using BigUint instead of usize?
The problem is that you first want to use a usize and then a BigUint as your function parameter, while your parameter is set to be a usize.
To fix this you should make your factorial function generic and then only allow those types that make sense for your particular method.
I took your example and extended it to allow for all unsigned integer types:
use num_bigint::BigUint;
use num_traits::{One, FromPrimitive, Unsigned};
use num::{Integer, NumCast, ToPrimitive};
fn factorial<N: Unsigned + Integer + ToPrimitive>(n: N) -> BigUint {
let mut f: BigUint = One::one();
let end: usize = NumCast::from(n).unwrap();
for i in 1..(end + 1) {
let bu: BigUint = FromPrimitive::from_usize(i).unwrap();
f = f * bu;
}
f
}
pub fn main() {
println!("Starting calculation...");
println!("{}", factorial(factorial(5 as u32)));
}
This will however lead to not allowing factorial(5), because 5 is treated as an i32 by default, which can be signed. If you wish to allow for signed types and instead fail at runtime you can do something like that:
use num_bigint::BigUint;
use num_traits::{One, FromPrimitive};
use num::{Integer, NumCast, ToPrimitive};
fn factorial<N: Integer + ToPrimitive>(n: N) -> BigUint {
let mut f: BigUint = One::one();
let end: usize = NumCast::from(n).expect("Number too big or negative number used.");
for i in 1..(end + 1) {
let bu: BigUint = FromPrimitive::from_usize(i).unwrap();
f = f * bu;
}
f
}
pub fn main() {
println!("Starting calculation...");
println!("{}", factorial(factorial(5)));
}

How do I concatenate a vector of integers into a single integer?

I'm trying to concatenate all of the contents of a vector into a single number. This would be like [1, 2, 4] -> 124. Here's what I have right now:
fn sumVector(vec: &Vec<u32>) -> u32 {
return vec.to_owned().concat();
}
This is failing with error
error[E0599]: no method named `concat` found for type `std::vec::Vec<u32>` in the current scope
--> src/lib.rs:2:27
|
2 | return vec.to_owned().concat();
| ^^^^^^ method not found in `std::vec::Vec<u32>`
As said in the comments by Stargateur, you can do:
fn concat(vec: &[u32]) -> u32 {
vec.iter().fold(0, |acc, elem| acc * 10 + elem)
}
You can also write the same function in imperative style:
fn concat(vec: &[u32]) -> u32 {
let mut acc = 0;
for elem in vec {
acc *= 10;
acc += elem;
}
acc
}
You can follow Ortomala Lokni's procedure if your input vector contains single digit integers.
If the vector contains multi-digit integers, the function may not return the intended value. The following concat_new function handles this case.
fn main() {
let a = vec![10_i32, 20, 300];
println!("{:?}", concat_new(&a));
println!("{:?}", concat(&a));
}
fn concat_new(vec: &[i32]) -> i32 {
let t = vec.iter().fold("".to_string(), |acc, x| acc + &x.to_string());
t.parse::<i32>().unwrap()
}
fn concat(vec: &[i32]) -> i32 {
vec.iter().fold(0, |acc, elem| acc * 10 + elem)
}

Two dimensional vectors in Rust

Editor's note: This question predates Rust 0.1 (tagged 2013-07-03) and is not syntactically valid Rust 1.0 code. Answers may still contain valuable information.
Does anyone know how to create mutable two-dimensional vectors in Rust and pass them to a function to be manipulated?
This is what I tried so far:
extern crate std;
fn promeni(rec: &[u8]) {
rec[0][1] = 0x01u8;
}
fn main() {
let mut rec = ~[[0x00u8,0x00u8],
[0x00u8,0x00u8]
];
io::println(u8::str(rec[0][1]));
promeni(rec);
io::println(u8::str(rec[0][1]));
}
You could use the macro vec! to create 2d vectors.
fn test(vec: &mut Vec<Vec<char>>){
vec[0][0] = 'd';
..//
vec[23][79] = 'd';
}
fn main() {
let mut vec = vec![vec!['#'; 80]; 24];
test(&mut vec);
}
Did you intend that all of the subarrays will have the length 2, as in this example? In that case, the type of the parameter should not be &[u8], which is a borrowed array of u8's, but rather &[[u8; 2]].
If the functions that is going to manipulate are yours, you can create a custom struct with the helper methods to treat the vector as 2d:
use std::fmt;
#[derive(Debug)]
pub struct Vec2d<T> {
vec: Vec<T>,
row: usize,
col: usize,
}
impl<T> Vec2d<T> {
pub fn new(vec: Vec<T>, row: usize, col: usize) -> Self {
assert!(vec.len() == row * col);
Self { vec, row, col }
}
pub fn row(&self, row: usize) -> &[T] {
let i = self.col * row;
&self.vec[i..(i + self.col)]
}
pub fn index(&self, row: usize, col: usize) -> &T {
let i = self.col * row;
&self.vec[i + col]
}
pub fn index_mut(&mut self, row: usize, col: usize) -> &mut T {
let i = self.col * row;
&mut self.vec[i + col]
}
}
impl<T: std::fmt::Debug> std::fmt::Display for Vec2d<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut str = String::new();
for i in 0..self.row {
if i != 0 {
str.push_str(", ");
}
str.push_str(&format!("{:?}", &self.row(i)));
}
write!(f, "[{}]", str)
}
}
fn main() {
let mut mv = Vec2d::new(vec![1, 2, 3, 4, 5, 6], 2, 3);
*mv.index_mut(1, 2) = 10;
println!("Display: {}", mv);
println!("Debug: {:?}", mv);
}
The associated function new creates the Vec2d, have two main methods (index and index_mut, so you can get a index value borrowed immut ou mut) and added a Display trait to visualise it better (but it is stored as Vec<>).

Resources