///|
fn vector_dot(
a : Array[Double],
b : Array[Double],
) -> Double raise KineticsError {
if a.length() != b.length() {
raise Invalid("dot product shape")
}
let mut sum = 0.0
for i in 0.. Array[Double] raise KineticsError {
if weights.length() != self.names.length() {
raise Invalid("conservation shape")
}
let s = self.stoichiometry()
let result = Array::make(self.reactions.length(), 0.0)
for j in 0.. Array[Array[Double]] raise KineticsError {
finite(tolerance, "tolerance")
if tolerance <= 0.0 || tolerance > 1.0e-3 {
raise Invalid("conservation tolerance")
}
let n = self.names.length()
let a = self.reactions.map(r => {
Array::makei(n, i => (r.output[i] - r.input[i]).to_double())
})
let pivots : Array[Int32] = []
let mut row = 0
for col in 0.. magnitude {
best = k
magnitude = a[k][col].abs()
}
}
if magnitude == tolerance {
continue
}
let temp = a[row]
a[row] = a[best]
a[best] = temp
let pivot = a[row][col]
for j in col.. tolerance * 100.0 {
raise Numerical("unstable conservation basis")
}
}
basis.push(vector)
}
basis
}
///|
pub fn conserved_value(
weights : Array[Double],
values : Array[Double],
) -> Double raise KineticsError {
vector_dot(weights, values)
}