1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file Fit/Param/Parameters.cpp
//! @brief Defines class Parameters.
//!
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
// ************************************************************************************************
#include "Fit/Param/Parameters.h"
#include <cmath>
#include <sstream>
#include <stdexcept>
using namespace mumufit;
void Parameters::add(const Parameter& par)
{
if (exists(par.name()))
throw std::runtime_error("Parameters::add -> Error. Parameter with the name '" + par.name()
+ "' already exists.");
m_parameters.push_back(par);
}
std::vector<double> Parameters::values() const
{
std::vector<double> result;
for (const auto& par : m_parameters)
result.push_back(par.value());
return result;
}
void Parameters::setValues(const std::vector<double>& values)
{
check_array_size(values);
size_t index = 0;
for (auto& par : m_parameters) {
if (std::isnan(values[index]))
throw std::runtime_error("Parameters::setValues -> Error."
" Attempt to set nan '"
+ par.name() + "'.");
if (std::isinf(values[index]))
throw std::runtime_error("Parameters::setValues -> Error. Attempt to set inf '"
+ par.name() + "'.");
par.setValue(values[index]);
++index;
}
}
std::vector<double> Parameters::errors() const
{
std::vector<double> result;
for (const auto& par : m_parameters)
result.push_back(par.error());
return result;
}
void Parameters::setErrors(const std::vector<double>& errors)
{
check_array_size(errors);
size_t index = 0;
for (auto& par : m_parameters)
par.setError(errors[index++]);
}
const Parameter& Parameters::operator[](const std::string& name) const
{
for (const auto& par : m_parameters)
if (par.name() == name)
return par;
std::ostringstream ostr;
ostr << "Parameters::operator[] -> Error. No parameter with name '" << name << "'. ";
ostr << "Existing names:\n";
for (const auto& par : m_parameters)
ostr << par.name() << "\n";
throw std::runtime_error(ostr.str());
}
const Parameter& Parameters::operator[](size_t index) const
{
return m_parameters[check_index(index)];
}
void Parameters::setCorrelationMatrix(const double2d_t& matrix)
{
if (matrix.size() != size())
throw std::runtime_error("Parameters::setCorrelationMatrix -> Error. Wrong "
"dimension of correlation matrix.");
m_corr_matrix = matrix;
}
//! Returns number of free parameters.
size_t Parameters::freeParameterCount() const
{
size_t result(0);
for (const auto& par : m_parameters)
if (!par.limits().isFixed())
result++;
return result;
}
bool Parameters::exists(const std::string& name) const
{
for (const auto& par : m_parameters)
if (par.name() == name)
return true;
return false;
}
void Parameters::check_array_size(const std::vector<double>& values) const
{
if (values.size() != m_parameters.size()) {
std::ostringstream ostr;
ostr << "Parameters::check_array_size -> Error. Size of input array " << values.size()
<< " doesn't mach number of fit parameters " << m_parameters.size() << "."
<< std::endl;
throw std::runtime_error(ostr.str());
}
}
size_t Parameters::check_index(size_t index) const
{
if (index >= m_parameters.size())
throw std::runtime_error("Parameters::check_index -> Index out of bounds");
return index;
}
|