Использование Boost.Units и Boost.Multiprecision

Я пытаюсь написать программу молекулярной динамики, и я подумал, что Boost.Units был логичным выбором для переменных, и я также решил, что Boost.Multiprecision предлагает лучший вариант, чем double или же long double в отношении ошибок округления. Комбинация из двух кажется довольно простой, пока я не попытаюсь использовать константу, а затем она сломается.

#include <boost/multiprecision/gmp.hpp>
#include <boost/units/io.hpp>
#include <boost/units/pow.hpp>
#include <boost/units/quantity.hpp>
#include <boost/units/systems/si.hpp>
#include <boost/units/systems/si/codata/physico-chemical_constants.hpp>

namespace units = boost::units;
namespace si = boost::si;
namespace mp = boost::multiprecision;

units::quantity<si::mass, mp::mpf_float_50> mass = 1.0 * si::kilogram;
units::quantity<si::temperature, mp::mpf_float_50> temperature = 300. * si::kelvin;
auto k_B = si::constants::codata::k_B;  // Boltzmann constant
units::quantity<si::velocity, mp::mpf_float_50> velocity = units::root<2>(temperature * k_B / mass);
std::cout << velocity << std::endl;

Выход будет 1 M S^-1, Если я использую long double вместо mp::mpf_float_50то результат 2.87818e-11 m s^-1, Я знаю, что проблема нравится в преобразовании между константой и другими данными, потому что константа по умолчанию double, Я думал о создании своей собственной постоянной Больцмана, но я предпочитаю использовать предопределенное значение, если это возможно.

Поэтому мой вопрос, как мне использовать Boost.Multiprecision, когда у меня есть предопределенные константы из Boost.Units? Если я должен уступить использованию double или же long double, тогда я буду, но я подозреваю, что существует способ конвертировать или использовать другой на константах.

Я работаю с Mac OS X 10.7, Xcode 4.6.2, Clang 3.2, Boost 1.53.0 и расширениями C ++ 11.

Я ценю любую помощь, которая может быть предложена.

2

Решение

Я бы посоветовал вам не использовать арифметику с множественной точностью для моделирования молекулярной динамики, потому что интеграция с шагом по времени будет мучительно медленной. Если цель состоит в том, чтобы максимально сохранить общую энергию, то просто используйте Verlet или любой другой симплектический интегратор. Множественная точность арифметики (или long doubleили компенсированное суммирование с простым double) может быть полезен для агрегирования средних по ансамблю.

Кроме того, если вы напишите свой код моделирования с использованием безразмерных (сокращенных) единиц, вы также избавитесь от зависимости от Boost.Units.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]