Я работаю с векторами силы от до шести степеней свободы, представляющих (Fx, Fy, Fz, Mx, My, Mz). В зависимости от желаемого использования мне обычно нужны только три степени свободы, то есть (Fx, Fy, Mz).
Мой первый инстинкт - использовать фиксированную длину ndarray::Array1
s размера (6,)
, хотя это будет означать ношение лишних нулей большую часть времени. Кажется очевидным, что это было бы проще всего с точки зрения реализации всей математики. Но без дальнейшего сокращения это приведет к выполнению линейной алгебры с использованием полных массовых матриц 6x6, которые наполовину пусты. Есть ли шанс, что enum
может предложить некоторую эффективность в этом отношении? Например:
pub enum ForceArr<F64> {
ThreeDOF([f64; 3]),
FourDOF([f64; 4]),
FiveDOF([f64; 5]),
SixDOF([f64; 6]),
}
Которую необходимо преобразовать в array1
s перед выполнением более сложных операций. Или:
use ndarray::Array1;
pub enum ForceArray<F64> {
ThreeDOF(Array1<f64>),
FourDOF(Array1<f64>),
FiveDOF(Array1<f64>),
SixDOF(Array1<f64>),
}
Хотя я не могу понять, как установить размер различных массивов во втором варианте, поэтому я предполагаю, что это будет менее эффективно. Я знаю, что перечисления имеют размер, равный размеру их наибольшего элемента плюс дискриминатор
Моей другой мыслью было перечисление, явно перечисляющее индексы полного массива 6DOF для получения уменьшенных представлений векторов / матриц, таких как как:
pub enum ForceIdxs<U8> {
ThreeDOF([u8; 3]) = [0, 1, 5],
FourDOF([u8; 4]) = [0, 1, 3, 5],
FiveDOF([u8; 5]) = [0, 1, 3, 4, 5],
SixDOF([u8; 6]) = [0, 1, 2, 3, 4, 5],
}
Но это все еще экспериментально: https://github.com/rust-lang/rust/issues/60553. Хотя это будет работать с моим первоначальным планом Array1
s размера (6,)
и позволит уменьшить векторы сил и массовые матрицы путем индексации, чтобы упростить выполнение операций линейной алгебры.
Я мог бы также настроить каждую функцию так, чтобы она просто обрабатывала эту операцию индексации вручную, что начинает казаться вариантом «лучшего из обоих миров» ...