Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add examples of efficient numerics #1

Open
dcnorris opened this issue Mar 16, 2021 · 1 comment
Open

Add examples of efficient numerics #1

dcnorris opened this issue Mar 16, 2021 · 1 comment

Comments

@dcnorris
Copy link

Thanks for this wonderful project. In under 24h, never having written any Rust code before, I have achieved a 2.5x speedup of an objective function that is invoked by base::integrate().

FYI, here is the original function from package dfcrm ...

crmh = function(a,x,y,w,s) {  ## posterior
  v = exp(-a^2/2/s^2) 
  for (i in 1:length(x)) {
	v = v * ((x[i]^exp(a))^y[i])*(((1-w[i]*x[i]^exp(a))^(1-y[i])))
  }
  return(v)
}

and here is my initial direct translation into Rust:

/// A Rust implementation of the dfcrm::crmh posterior,
/// which I hope will prove faster to integrate().
/// @export
#[extendr]
fn rcrmh(a: &[f64],
	 x: &[f64],
	 y: &[f64],
	 w: &[f64],
	 s: &[f64]) -> Robj {
    // TODO: Assert that x, y and w all have same length?
    let v = a.iter().map(|a| {
	let mut v_ = (-0.5*a/s[0]).exp();
	for i in 0 .. y.len() {
	    let p_i = x[i].powf(a.exp()); // 'power model' CRM
	    v_ = v_ * if y[i] == 0.0 { 1.0 - w[i] * p_i } else { p_i };
	}
	v_
    });
    v.collect_robj()
}

Speaking from the POV of the Rust novice, the sort of example I would find most helpful would show a cascade of performance improvements that start with 'elegant' or 'default' wrappings and proceed step-wise through a series of tuning steps that exploit language features like borrowing, etc. Alluding to equivalent constructs in C would help orient users who are familiar with performance-tuning tricks in that language.

@andy-thomason
Copy link
Contributor

Wow, thanks @dcnorris I do have a very fast vectorised exp/log that I hope to roll out in due course as part
of another long term project.

It is worth looking at the rayon package for parallel iterators if your vectors are large.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants