///|
/// Human-readable compact reporting helpers; no I/O is required.
pub fn format_double(value : Double, digits : Int) -> String {
let scale = @math.pow(10.0, digits.to_double())
let rounded = @math.round(value * scale) / scale
"\{rounded}"
}
///|
pub fn format_metric(metric : MetricEstimate) -> String {
"estimate=\{format_double(metric.estimate, 6)}, 95%=[\{format_double(metric.lower, 6)}, \{format_double(metric.upper, 6)}]"
}
///|
pub fn format_fit(fit : FitResult) -> String {
let parameters = fit.parameters
.map(value => format_double(value, 6))
.join(", ")
"\{fit.distribution}: parameters=[\{parameters}], log_likelihood=\{format_double(fit.log_likelihood, 4)}, AIC=\{format_double(fit.aic, 4)}, BIC=\{format_double(fit.bic, 4)}"
}
///|
pub fn survival_curve_csv(curve : SurvivalCurve) -> String {
let builder = StringBuilder::new()
builder.write_string(
"time,at_risk,events,censored,survival,standard_error,cumulative_hazard\n",
)
for point in curve.points {
builder.write_string(
"\{point.time},\{point.at_risk},\{point.events},\{point.censored},\{point.survival},\{point.standard_error},\{point.cumulative_hazard}\n",
)
}
builder.to_string()
}
///|
pub fn life_table_csv(table : LifeTable) -> String {
let builder = StringBuilder::new()
builder.write_string(
"lower,upper,exposed,failures,withdrawals,failure_probability,survival_probability,hazard\n",
)
for interval in table.intervals {
builder.write_string(
"\{interval.lower},\{interval.upper},\{interval.exposed},\{interval.failures},\{interval.withdrawals},\{interval.failure_probability},\{interval.survival_probability},\{interval.hazard}\n",
)
}
builder.to_string()
}
///|
pub fn regression_markdown(model : RegressionResult) -> String {
let builder = StringBuilder::new()
builder.write_string("| metric | value |\n|---|---:|\n")
builder.write_string("| observations | \{model.observations} |\n")
builder.write_string("| R² | \{format_double(model.r_squared, 6)} |\n")
builder.write_string(
"| adjusted R² | \{format_double(model.adjusted_r_squared, 6)} |\n",
)
builder.write_string(
"| residual sum of squares | \{format_double(model.residual_sum_squares, 6)} |\n",
)
builder.to_string()
}
///|
pub fn benchmark_markdown(results : Array[BenchmarkResult]) -> String {
let builder = StringBuilder::new()
builder.write_string(
"| benchmark | iterations | elapsed (µs) | operations/s | checksum |\n|---|---:|---:|---:|---:|\n",
)
for result in results {
builder.write_string(
"| \{result.name} | \{result.iterations} | \{result.elapsed_micros} | \{format_double(result.operations_per_second, 2)} | \{format_double(result.checksum, 6)} |\n",
)
}
builder.to_string()
}
///|
pub fn fit_report(fits : Array[FitResult]) -> String {
let builder = StringBuilder::new()
builder.write_string("# Reliability fit report\n\n")
for fit in fits {
builder.write_string("- \{format_fit(fit)}\n")
}
builder.to_string()
}
///|
pub fn observation_summary_markdown(summary : SampleSummary) -> String {
"| count | failures | censored | mean | median | sd |\n|---:|---:|---:|---:|---:|---:|\n| \{summary.count} | \{summary.failures} | \{summary.censored} | \{format_double(summary.mean, 4)} | \{format_double(summary.median, 4)} | \{format_double(summary.standard_deviation, 4)} |"
}