randomwalk

Build glorious random walks.

```rust use randomwalk::generators::NormalGenerator;

use randomwalk::translators::{ UniformTranslator, ExponentialTranslator, LogNormalTranslator, }; ```

Examples

Helper methods used in the examples

```rust // normal distribution between 0 and 1 let normdist = randdistr::Normal::new(0.0, 1.0).unwrap();

// exponential distribution with lambda of 0.0055 let expdist = randdistr::Exp::new(1.0 / 180.0).unwrap();

// uniform distribution between 0 and 1 let unifdist = randdistr::Uniform::new(0.0, 1.0);

let now = || chrono::Utc::now();

let mut rng = randhc::Hc128Rng::fromentropy(); ```

Normally distributed random walk with soft bound

This section demonstrates how to create a random walk that is soft bound to lie about its mean. To approximate a walk without a soft bound, give the variance a large value and use NormalGenerator.set to initialize the walk before calling NormalGenerator.next.

```rust let utc_now = now();

Setup a random walk with mean 100.0 and variance 250.0.

The variance controls how tightly the walk is held

close to its mean and sigma_xx controls how rapidly

it can wander away from its starting point.

let mut normalgen = NormalGenerator::new( 100.0, 250.0, 0.1, utcnow.timestamp() as u64, );

let mut currenttime = utcnow.timestampmillis() as f64; let mut currentvalue = normalgen.next(currenttime).unwrap();

for i in 1..10 { # pretend time lapsed currenttime = currenttime + (i as f64 * 500f64); currentvalue = normalgen.next(current_time).unwrap();

println!(
    "Normal walk value {} time {}",
    current_value,
    current_time,
);

} ```

Normally distributed random walk with soft bound and random shaped interpolation

This section demonstrates how to create a random walk that is soft bound to lie about the value of a shaping function.

```rust let utc_now = now();

// Setup a random walk with zero mean. Since we'll be // adding the value of the walk to the shaping functions, // using a walk with zero mean ensures that the walk will // wander around but will keep returning to the vicinity // of the shaping function. Reducing the variance will // keep the walk closer to the shaping function and // make its form more obvious.

let mut normalgen = NormalGenerator::new( 100.0, 250.0, 0.1, utcnow.timestamp() as u64, );

// The walk will consist of shaped transitions between // random points. The start variable represent the // starting point of a transition, which is usually // the 'current' time and value and the target variables // represent the end point of a transition - the value // the walk need to walk to and the time at which it // needs to be there.

let mut currenttime = utcnow.timestampmillis() as f64; let mut currentvalue = 0.0;

let mut starttime = currenttime; let mut startvalue = 100.0 + rng.sample(normdist) * 10.0;

let mut targettime = currenttime + rng.sample(expdist) + 5.0; let mut targetvalue = 100.0 + rng.sample(norm_dist) * 10.0;

for i in 1..10 { currenttime = currenttime + (i as f64 * 500f64);

if currenttime > targettime { starttime = currenttime; startvalue = currentvalue;

   target_time = current_time + rng.sample(exp_dist) + 5.0;
   target_value = 100.0 + rng.sample(norm_dist) * 10.0;

}

currentvalue = normalgen.nextinterpolant( currenttime, target_time, 0.0, ).unwrap();

let normalizedtime = (currenttime - starttime) / (targettime - start_time);

// linear //let shapingvalue = // targetvalue // + normalizedtime // + startvalue * (1.0 - normalized_time);

// smoothstep let shapingvalue = startvalue + (targetvalue - startvalue) * ( 3.0 * normalizedtime * normalizedtime - 2.0 * normalizedtime * normalizedtime * normalized_time);

// quarter //let shapingvalue = // startvalue // + (targetvalue - startvalue) // * ( // 1.0 - (1.0 - normalizedtime) // * (1.0 - normalizedtime) // ).sqrt();

//println!( // "Shaping function {}", // shaping_value, //);

//println!( // "Raw normal walk {}", // current_value, //);

println!( "Normal shaped interpolated walk {} @ {} target {} @ {}", currentvalue + shapingvalue, currenttime, targetvalue, target_time, ); } ```

Normally distributed random walk with soft bound and random unshaped interpolation

This section demonstrates how to create a random walk that freely interpolates between fixed points without the help of a shaping function.

```rust let utc_now = now();

// Setup a random walk with mean 100.0 and variance 250.0. // The variance controls how tightly the walk is held // close to its mean and sigma_xx controls how rapidly it // can wander away from its starting point.

let mut normalgen = NormalGenerator::new( 100.0, 250.0, 0.1, utcnow.timestamp() as u64, );

// The walk will consist of unshaped transitions between // random points. The start variable represent the // starting point of a transition, which is usually // the 'current' time and value and the target variables // represent the end point of a transition - the value // the walk need to walk to and the time at which it // needs to be there.

let mut currenttime = utcnow.timestampmillis() as f64; let mut currentvalue = normalgen.next(currenttime).unwrap();

let mut targettime = currenttime + rng.sample(expdist) + 5.0; let mut targetvalue = 100.0 + rng.sample(norm_dist) * 10.0;

for i in 1..10 { currenttime = currenttime + (i as f64 * 500f64);

if currenttime > targettime { targettime = currenttime + rng.sample(expdist) + 5.0; targetvalue = 100.0 + rng.sample(norm_dist) * 10.0; }

currentvalue = normalgen.nextinterpolant( currenttime, targettime, targetvalue, ).unwrap();

println!( "Normal unshaped interpolated walk {} @ {} target {} @ {}", currentvalue, currenttime, targetvalue, targettime, ); } ```

Log-Normally distributed random walk with soft bound

This section demonstrates how to create a log-normally distributed random walk. This is achieved by generating a normally distributed random walk and passing it through and log-normal translator that postprocesses it to have a log-normal distribution.

```rust let utc_now = now();

// Generate a normally distributed random walk and attach // it to a log-normal translator. Note that the // log-normal translator raises the normal random walk // to the power of e so we need to setup the mean // and variance of the normal distribution so that // the output of the log-normal translator has the // properties that we want.

let mut normalgen = NormalGenerator::new( 100.0, 250.0 / 100.0 / 100.0, 0.1 / 100.0 / 100.0, utcnow.timestamp() as u64, );

let mut loggen = LogNormalTranslator::new( normalgen, );

let mut currenttime = utcnow.timestampmillis() as f64; let mut currentvalue = loggen.next(currenttime).unwrap();

for i in 1..10 { currenttime = currenttime + (i as f64 * 500f64);

currentvalue = loggen.next( current_time, ) .unwrap();

println!( "Log-Normal walk {}", current_value, ); } ```

Log-Normally distributed random walk with soft bound and random interpolations

This section demonstrates how to create a log-normally distributed random walk with unshaped random interpolations. For detailed comments please see the section for the log-normally distributed random walk and the normally distributed random walk with unshaped interpolations.

```rust let utc_now = now();

let mut normalgen = NormalGenerator::new( 100.0, 250.0 / 100.0 / 100.0, 0.1 / 100.0 / 100.0, utcnow.timestamp() as u64, );

let mut loggen = LogNormalTranslator::new( normalgen, );

let mut currenttime = utcnow.timestampmillis() as f64; let mut currentvalue = loggen.next(currenttime).unwrap();

for i in 1..10 { currenttime = currenttime + (i as f64 * 500f64);

currentvalue = loggen.next( current_time, ) .unwrap();

println!( "Log-Normal softbound walk {}", current_value, ); } ```

Uniformly distributed random walk with soft bound

This section demonstrates how to create a uniformly distributed random walk. This is achieved by setting up a normally-distributed random walk and attaching it to a uniform translator, which converts it into a uniformly distributed random walk.

```rust let utc_now = now();

// This section demonstrates how to create a uniformly // distributed random walk. This is achieved by setting // up a normally-distributed random walk and attaching // it to a uniform translator, which converts it into // a uniformly distributed random walk.

let mut normalgen = NormalGenerator::new( 100.0, 250.0, 0.0001, utcnow.timestamp() as u64, );

let mut uniformtx = UniformTranslator::new( normalgen, );

let mut currenttime = utcnow.timestamp_millis() as f64;

let mut currentvalue = uniformtx.next( current_time, ) .unwrap();

for i in 1..10 { currenttime = currenttime + (i as f64 * 500f64);

currentvalue = uniformtx.next( current_time, ) .unwrap();

println!( "Uniform walk with softbound {} @ {}", currentvalue, currenttime, ); } ```

Uniformly distributed random walk with soft bound and random interpolation

This section demonstrates how to create a uniformly distributed random walk with unshaped random interpolations. For detailed comments please see the section for the uniformly distributed random walk and the normally distributed random walk with unshaped interpolations.

```rust let utc_now = now();

let mut normalgen = NormalGenerator::new( 100.0, 250.0, 0.0001, utcnow.timestamp() as u64, );

let mut uniformtx = UniformTranslator::new( normalgen, );

let mut currenttime = utcnow.timestamp_millis() as f64;

let mut currentvalue = uniformtx.next( current_time, ) .unwrap();

let mut targettime = currenttime + rng.sample(exp_dist) + 5.0;

let mut targetvalue = rng.sample(unifdist);

for i in 1..10 { currenttime = currenttime + (i as f64 * 500f64);

if currenttime > targettime { targettime = currenttime + rng.sample(exp_dist) + 5.0;

   target_value =
       rng.sample(unif_dist);

}

currentvalue = uniformtx.nextinterpolant( currenttime, targettime, targetvalue, ) .unwrap();

println!( "Uniform interpolated walk with softbound {} @ {} target {} @ {}", currentvalue, currenttime, targetvalue, targettime, ); } ```

Exponentially distributed random walk with soft bound

This section demonstrates how to create an expoentially distributed random walk. This is done by creating a normally distributed random walk and attaching it to a uniform translator to convert it to a uniformly distributed walk. The uniform translator is then attached to an exponential translator that converts the uniformly distributed walk into an exponentially distributed random walk. Note that the exponentially distributed random walk takes larger steps when it has a larger value.

```rust let utcnow = now(); let time = utcnow.timestamp() as u64;

let normal_gen = NormalGenerator::new( 100.0, 250.0, 0.000001, time, );

let uniformtx = UniformTranslator::new( normalgen, );

let mut exptx = ExponentialTranslator::new( 100.0, uniformtx, ).unwrap();

let mut currenttime = utcnow.timestamp_millis() as f64;

let mut currentvalue = exptx.next( current_time, ) .unwrap();

for i in 1..10 { currenttime = currenttime + (i as f64 * 500f64);

currentvalue = exptx.next( current_time, ) .unwrap();

println!( "Exponential walk with softbound {} @ {}", currentvalue, currenttime, ); } ```

Exponentially distributed random walk with soft bound and random interpolations

This section demonstrates how to create a exponentially distributed random walk with unshaped random interpolations. For detailed comments please see the section for the exponentially distributed random walk and the normally distributed random walk with unshaped interpolations.

```rust let utcnow = now(); let time = utcnow.timestamp() as u64;

let normal_gen = NormalGenerator::new( 100.0, 250.0, 0.000001, time, );

let uniformtx = UniformTranslator::new( normalgen, );

let mut exptx = ExponentialTranslator::new( 100.0, uniformtx, ).unwrap();

let mut currenttime = utcnow.timestamp_millis() as f64;

let mut currentvalue = exptx.next( current_time, ) .unwrap();

let mut targettime = currenttime + rng.sample( exp_dist, ) + 5.0;

let mut targetvalue = 100.0 + rng.sample( normdist, ) * 10.0;

for i in 1..10 { currenttime = currenttime + (i as f64 * 500f64);

if currenttime > targettime { targettime = currenttime + rng.sample( exp_dist, ) + 5.0;

   target_value =
       100.0
           + rng.sample(
           norm_dist,
       )
           * 10.0;

}

currentvalue = exptx.nextinterpolant( currenttime, targettime, targetvalue, ) .unwrap();

println!( "Exponential interpolated walk with softbound {} @ {} target {} @ {}", currentvalue, currenttime, targetvalue, targettime, ); } ```