Я разрабатываю научное приложение (моделирование хромосом, движущихся в ядре клетки). Хромосомы разделены на небольшие фрагменты, которые вращаются вокруг случайной оси с использованием матриц вращения 4x4.
Проблема заключается в том, что симуляция выполняет сотни миллиардов оборотов, поэтому ошибки округления с плавающей запятой складываются и растут экспоненциально, поэтому фрагменты стремятся "отплыть" и отходить от остальной хромосомы по прошествии времени.
Я использую двойную точность с С++. На данный момент мягкие запускаются на CPU, но будут перенесены на CUDA, а симуляции могут длиться максимум 1 месяц.
Я понятия не имею, как я мог как-то перенормировать хромосому, потому что все фрагменты соединены вместе (вы можете видеть это как дважды связанный список), но я думаю, что это была бы лучшая идея, если это возможно.
Есть ли у вас предложения? Я чувствую себя немного потерянным.
Большое спасибо,
Н.
EDIT: Добавлен упрощенный пример кода. Вы можете предположить, что все математические матрицы являются классическими реализациями.
// Rotate 1000000 times
for (int i = 0; i < 1000000; ++i)
{
// Pick a random section start
int istart = rand() % chromosome->length;
// Pick the end 20 segments further (cyclic)
int iend = (istart + 20) % chromosome->length;
// Build rotation axis
Vector4 axis = chromosome->segments[istart].position - chromosome->segments[iend].position;
axis.normalize();
// Build rotation matrix and translation vector
Matrix4 rotm(axis, rand() / float(RAND_MAX));
Vector4 oldpos = chromosome->segments[istart].position;
// Rotate each segment between istart and iend using rotm
for (int j = (istart + 1) % chromosome->length; j != iend; ++j, j %= chromosome->length)
{
chromosome->segments[j].position -= oldpos;
chromosome->segments[j].position.transform(rotm);
chromosome->segments[j].position += oldpos;
}
}