///|
// All factors are nonnegative; pre-scan zeros to avoid spurious overflow.
// Reject unrepresentable positive intermediates rather than invent absorption.
fn monomial(
rate : Double,
state : Array[Double],
powers : Array[Int32],
) -> Double raise KineticsError {
if rate == 0.0 {
return 0.0
}
for i in 0.. 0 && state[i] == 0.0 {
return 0.0
}
}
let mut result = rate
for i in 0.. Array[Double] raise KineticsError {
self.validate_concentrations(concentrations)
let values : Array[Double] = []
for r in self.reactions {
let value = monomial(r.rate, concentrations, r.input)
values.push(value)
}
values
}
///|
pub fn Network::drift(
self : Network,
concentrations : Array[Double],
) -> Array[Double] raise KineticsError {
let fluxes = self.fluxes(concentrations)
let result = Array::make(self.names.length(), 0.0)
for j in 0.. Array[Double] raise KineticsError {
self.validate_counts(state)
let values : Array[Double] = []
for r in self.reactions {
let mut order = 0
let mut disabled = false
for i in 0.. 4 {
raise Invalid("unsupported reaction order")
}
finite(value, "propensity")
values.push(value)
}
values
}
///|
pub fn Network::total_propensity(
self : Network,
state : Array[Int32],
) -> Double raise KineticsError {
let mut total = 0.0
for a in self.propensities(state) {
total += a
finite(total, "total propensity")
}
total
}
///|
/// Counts drift, not concentration drift; finite-copy corrections are retained.
pub fn Network::count_drift(
self : Network,
state : Array[Int32],
) -> Array[Double] raise KineticsError {
let a = self.propensities(state)
let result = Array::make(self.names.length(), 0.0)
for j in 0..