///|
/// Shape and numeric errors from generic coupling-plan utilities.
pub(all) enum CouplingError {
  EmptyCoupling
  EmptyCouplingRow(Int)
  RaggedCouplingRow(Int, Int, Int)
  NonFiniteCouplingEntry(Int, Int)
  NegativeCouplingEntry(Int, Int)
  CostRowCountMismatch
  CostColumnCountMismatch(Int)
  NonFiniteCost(Int, Int)
  NegativeCost(Int, Int)
  NumericalOverflow(Int, Int)
}

///|
/// Row and column sums of a dense coupling matrix.
pub(all) struct CouplingMarginals {
  source : Array[Double]
  target : Array[Double]
}

///|
/// Validate a non-empty dense coupling and return its column count.
fn validate_coupling(
  coupling : Array[Array[Double]],
) -> Result[Int, CouplingError] {
  if coupling.length() == 0 {
    return Err(CouplingError::EmptyCoupling)
  }
  let columns = coupling[0].length()
  if columns == 0 {
    return Err(CouplingError::EmptyCouplingRow(0))
  }
  for i in 0.. Result[CouplingMarginals, CouplingError] {
  let columns = match validate_coupling(coupling) {
    Err(error) => return Err(error)
    Ok(value) => value
  }
  let source = Array::make(coupling.length(), 0.0)
  let target = Array::make(columns, 0.0)
  for i in 0..` of a dense coupling.
///
/// The plan and cost matrix must be non-empty rectangular matrices with the
/// same shape. Coupling entries and costs must be finite and nonnegative. This
/// diagnostic is distinct from the entropy-regularized objective returned by
/// the solver.
pub fn coupling_transport_cost(
  coupling : Array[Array[Double]],
  cost : Array[Array[Double]],
) -> Result[Double, CouplingError] {
  let columns = match validate_coupling(coupling) {
    Err(error) => return Err(error)
    Ok(value) => value
  }
  if cost.length() != coupling.length() {
    return Err(CouplingError::CostRowCountMismatch)
  }
  let mut total = 0.0
  for i in 0..