| Crates.io | blprs |
| lib.rs | blprs |
| version | 0.0.1 |
| created_at | 2025-10-02 18:04:28.657396+00 |
| updated_at | 2025-10-02 18:04:28.657396+00 |
| description | Fast Berry–Levinsohn–Pakes (BLP) estimation for random coefficients logit models |
| homepage | |
| repository | https://github.com/emaadmanzoor/blprs |
| max_upload_size | |
| id | 1864766 |
| size | 73,647 |
Fast Berry–Levinsohn–Pakes (BLP) estimation for random coefficients logit models, written in Rust. The goal of blprs is to provide a feature-complete and performant alternative to pyBLP, accompanied by rich inline documentation and an ergonomic Rust-first API.
⚠️ This is an early preview. The demand-side estimator is implemented, but advanced functionality (supply, optimal instruments, bootstrapping, simulation aides, and the full suite of
pyBLPconveniences) is still under construction.
pyBLP notebooks.unsafe code; builds on nalgebra, rayon, and serde.Add the crate once it is published:
cargo add blprs
For now, use a Git dependency while the crate incubates:
[dependencies]
blprs = { git = "https://github.com/eam398/blprs" }
use blprs::{ContractionOptions, Problem, ProblemOptions, WeightingMatrix};
use blprs::data::ProductDataBuilder;
use blprs::integration::SimulationDraws;
use nalgebra::{DMatrix, DVector};
let market_ids = vec!["m1".to_string(), "m1".to_string(), "m2".to_string()];
let shares = DVector::from_vec(vec![0.3, 0.2, 0.4]);
let x1 = DMatrix::from_row_slice(3, 2, &[1.0, 10.0, 1.0, 15.0, 1.0, 12.0]);
let x2 = DMatrix::from_row_slice(3, 1, &[10.0, 15.0, 12.0]);
let products = ProductDataBuilder::new(market_ids, shares)
.x1(x1)
.x2(x2)
.build()
.expect("validated product data");
let draws = SimulationDraws::standard_normal(200, 1, 1234);
let problem = Problem::builder()
.products(products)
.draws(draws)
.options(ProblemOptions::default())
.build()
.unwrap();
let sigma = DMatrix::from_row_slice(1, 1, &[2.0]);
let options = ProblemOptions::default()
.with_contraction(ContractionOptions { tolerance: 1e-10, ..Default::default() })
.with_weighting(WeightingMatrix::InverseZTZ);
let result = problem.solve_with_options(&sigma, &options).unwrap();
println!("beta = {:?}", result.beta);
println!("GMM objective = {}", result.gmm_value);
data: builders and validation for product-level matrices (X1, X2, instruments).integration: Monte Carlo draws with shape checking and seeded reproducibility.demand: share prediction and the BLP contraction mapping.solving: solver configuration and diagnostics.estimation: high-level BlpProblem wrapper that mirrors pyblp.Problem for the demand side.Contributions and feature requests are welcome via pull requests or GitHub discussions.
cargo fmt
cargo clippy
cargo test
Licensed under the MIT License. See LICENSE for details.