Migrating from legacy rcr to rcrpy¶
The legacy package on PyPI (rcr) is a pybind11 wrapper around the C++
implementation at ../../cpp/. rcrpy is a pure-Python
reimplementation: same algorithm, same answers (Phase 1 bit-identical at
rtol=1e-12; Phase 2 within rtol=5%), but no C++ toolchain needed and
significantly faster on functional-form fits.
The APIs are intentionally close. This page is a direct translation table.
Imports¶
# Before
import rcr
# After
import rcrpy
Constants and enums¶
Legacy |
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Methods (camelCase → snake_case)¶
Legacy |
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Result fields (camelCase → snake_case)¶
Legacy |
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FunctionalForm¶
Constructor signature is the same; result fields renamed.
# Before
model = rcr.FunctionalForm(f, xdata, ydata, partials, guess,
weights=w, error_y=ey)
print(model.result.parameters)
print(model.result.parameter_uncertainties)
print(model.result.pivot)
print(rcr.FunctionalForm.pivot)
# After (identical, modulo `rcr → rcrpy` and field naming)
model = rcrpy.FunctionalForm(f, xdata, ydata, partials, guess,
weights=w, error_y=ey)
print(model.result.parameters)
print(model.result.parameter_uncertainties)
print(model.result.pivot)
print(rcrpy.FunctionalForm.pivot)
The pivot static-class attribute works the same way — your model
function can reference rcrpy.FunctionalForm.pivot inline.
Priors¶
Same constructor signatures and meanings; argument names converted to snake_case.
# Before
mypriors = rcr.Priors(rcr.MIXED_PRIORS, gaussianParams, paramBounds)
# After
mypriors = rcrpy.Priors(prior_type=rcrpy.PriorType.MIXED,
gaussian_params=gaussian_params,
param_bounds=param_bounds)
NonParametric¶
Subclass the same way; override mu_func (and optionally mu_func_w)
in Python instead of muFunc in C++.
class MyModel(rcrpy.NonParametric):
def mu_func(self, flags, y):
# Decide which points contribute to the mu estimate this iteration.
idx = your_filter(flags, y)
self.indices = idx.astype(np.int64)
return idx, y[idx]
What rcrpy does NOT include from legacy rcr¶
Feature |
Status |
|---|---|
Direct pybind11 binding to C++ |
Not applicable — |
Sphinx-rendered docstrings exactly matching legacy |
|
|
Not implemented (our solvers don’t produce the legacy’s M+1 signal) |
100% bit-identical MEDIAN/MODE for parametric |
Different RNG between Python and C++’s |
For Phase 1 (single-value RCR), parity is bit-identical at rtol=1e-12.
Performance¶
Workload |
Legacy (C++) |
|
|---|---|---|
Single-value RCR, large N |
Baseline |
~10× slower |
Functional-form fit, no rejection |
Baseline |
80×–6000× FASTER |
Functional-form fit + LS_MODE_68 |
Baseline |
~10–400× faster |
The functional-form speedup comes from scipy.optimize.least_squares
making far fewer Python↔C++ callback round-trips than the legacy’s
hand-rolled Gauss-Newton solver. See ../benchmarks/diagnostics_functional.py.