///|
/// Complete cumulative development table, preserving every observed value.
/// Includes an additional tail column only when tail>1.
pub fn Estimate::projected_cumulative(
self : Estimate,
triangle : Triangle,
) -> Array[Array[Double]] raise RunoffError {
compatible(triangle, self.pattern)
let out : Array[Array[Double]] = []
for origin in 0.. 1.0 {
row.push(self.origins[origin].ultimate)
}
// Ultimate is exact at the final development or tail column.
row[row.length() - 1] = self.origins[origin].ultimate
out.push(row)
}
out
}
///|
/// Add portfolios cell-wise before fitting. This does not average fitted factors.
pub fn Triangle::combine(
self : Triangle,
other : Triangle,
) -> Triangle raise RunoffError {
if self.order() != other.order() {
raise Shape("combined triangles must have matching geometry")
}
let rows : Array[Array[Double]] = []
for i in 0.. Triangle raise RunoffError {
if weights.length() != self.order() {
raise Shape("restatement weight count differs from order")
}
let rows : Array[Array[Double]] = []
for i in 0..