In a previous post, I wrote a function to perform repeated timings of untyped and typed versions of the same Racket functions.
#lang racket (require math) (define (time-apply-cpu-old proc lst reps) (define out (for/list ([i (in-range reps)]) (define-values (results cpu-time real-time gc-time) (time-apply proc lst)) cpu-time)) (displayln (string-append "min: " (number->string (apply min out)) " mean: " (number->string (round (mean out))) " max: " (number->string (apply max out)) " function: " (symbol->string (object-name proc))))) time-apply-cpu-old is a wrapper function for time-apply from racket/base that runs time-apply repeatedly and prints the min, mean, and max cpu time.

In a previous post, I wrote that Racket’s if is similar to ifelse in R. That’s not quite right. This is a short post to clarify the comparison. The more accurate description is that this Racket code
(if (test-expr) true-expr false-expr) is the same as this R code.
if (test_expr){ true_expr }else{ false_expr } In contrast, R’s ifelse function is vectorized meaning that the same operation is applied to multiple elements of a vector.

On my journey to learn Racket, I look for small pieces of R code to try to implement in Racket. A blog post about speeding up population simulations in R with the Rcpp package seemed like a good candidate for implementing in Racket. I was particularly interested in the (superficial?) parallels between R/Rcpp and Racket/Typed Racket.
Running a single simulation First, let’s get some of the setup code1 out of the way.

R makes it easy to generate random numbers from a wide variety of distributions with a consistent interface. For example, runif, rnorm, and rpois generate random numbers from uniform, normal, and Poisson distributions, respectively.
> x = runif(n = 1000, min = 4.6, max = 9.3) > min(x) [1] 4.60374 > max(x) [1] 9.288063 > > y = rnorm(n = 1000, mean = 81, sd = 9) > mean(y) [1] 81.

When programming in R, I generally pass data around by reading and writing text files (typically, CSV files). The ubiquity of CSV files means that many different types of software will open them easily (e.g., Notepad, Excel, TextEdit, etc.). However, if the data structure is not flat or contains other attributes, then writing to CSV requires flattening and/or dropping attributes. The general solution to writing data to a file while retaining structure and attributes is serialization.

When building a simulation model in R, I might want to group related input parameters into a data structure. For example, in a life cycle model with resident and anadromous fish, you might use different fecundity parameters for each life history type. One option is to create different objects for each fecundity parameter.
fecundity_resident = 1000 fecundity_anadromous = 4000 That option is not unreasonable with only two fecundity parameters but it becomes cluttered with many values.

I have recently started learning Racket. For a first task, I tried to build a simple age-structured population model. I hit a stumbling block and reached out to the helpful folks on the Racket mailing list. In this post, I recap the mailing list exchange with a target audience of R programmers that are interested in learning more about Racket.
The simple model used for this exercise is a deterministic multistage Beverton-Holt model.

© 2018-2019 Travis Hinkelman · Powered by the Academic theme for Hugo.