//---------------------------------------------------------------------- // Includes //---------------------------------------------------------------------- #include "MantidAPI/FunctionValues.h" #include <algorithm> namespace Mantid { namespace API { /** * Constructs a set of output values based on the given domain. * @param domain :: A reference to the domain over which the function is * calculated */ FunctionValues::FunctionValues(const FunctionDomain &domain) { reset(domain); } /** Copy constructor. * @param values :: Values to copy from. */ FunctionValues::FunctionValues(const FunctionValues &values) : m_calculated(values.m_calculated), m_data(values.m_data), m_weights(values.m_weights) {} /// Destructor FunctionValues::~FunctionValues() {} /// Reset the values to match a new domain. void FunctionValues::reset(const FunctionDomain &domain) { if (domain.size() == 0) { throw std::invalid_argument("FunctionValues cannot have zero size."); } m_calculated.resize(domain.size()); } /** * Expand to a new size. Preserve old values. Do not contract. * @param n :: A new size, must be greater than the current size. */ void FunctionValues::expand(size_t n) { if (n < size()) { throw std::invalid_argument("Cannot make FunctionValues smaller"); } m_calculated.resize(n); if (!m_data.empty()) { m_data.resize(n); } if (!m_weights.empty()) { m_weights.resize(n); } } /** Set all calculated values to same number. * @param value :: A new value. */ void FunctionValues::setCalculated(double value) { std::fill(m_calculated.begin(), m_calculated.end(), value); } /** * Get a pointer to calculated data at index i * @param i :: Index. */ double *FunctionValues::getPointerToCalculated(size_t i) { if (i < size()) { return &m_calculated[i]; } throw std::out_of_range("FunctionValue index out of range."); } /// Set all calculated values to zero void FunctionValues::zeroCalculated() { setCalculated(0.0); } /** * Copy calculated values to a buffer * @param to :: Pointer to the buffer */ void FunctionValues::copyTo(double *to) const { std::copy(m_calculated.begin(), m_calculated.end(), to); } /** Add calculated values to values in a buffer and save result to the buffer * @param to :: Pointer to the buffer, it must be large enough */ void FunctionValues::add(double *to) const { std::transform(m_calculated.begin(), m_calculated.end(), to, to, std::plus<double>()); } /** Multiply calculated values by values in a buffer and save result to the * buffer * @param to :: Pointer to the buffer, it must be large enough */ void FunctionValues::multiply(double *to) const { std::transform(m_calculated.begin(), m_calculated.end(), to, to, std::multiplies<double>()); } /** * Add other calculated values to this. * @param values :: An instance of FunctionValues to be added to this. Must have * the same size to this. * @return A reference to this values. */ FunctionValues &FunctionValues::operator+=(const FunctionValues &values) { if (size() != values.size()) { throw std::runtime_error("Cannot add values: sizes do not match"); } values.add(getPointerToCalculated(0)); return *this; } /** * Multiply by other calculated values. * @param values :: An instance of FunctionValues to multiply to this. Must have * the same size to this. * @return A reference to this values. */ FunctionValues &FunctionValues::operator*=(const FunctionValues &values) { if (size() != values.size()) { throw std::runtime_error("Cannot multiply values: sizes do not match"); } values.multiply(getPointerToCalculated(0)); return *this; } /** * Add other calculated values to these values starting from some index. * @param start :: A starting index for addition * @param values :: An instance of FunctionValues to be added to this. The size * mustn't exceed the number of * values in this from start to the end. * @return A reference to this values. */ void FunctionValues::addToCalculated(size_t start, const FunctionValues &values) { if (start + size() < values.size()) { throw std::runtime_error("Cannot add values: sizes do not match"); } values.add(getPointerToCalculated(start)); } /** * Set a fitting data value. * @param i :: A value index * @param value :: A new value to set. */ void FunctionValues::setFitData(size_t i, double value) { if (m_data.size() != m_calculated.size()) { m_data.resize(m_calculated.size()); } m_data[i] = value; } /** * Set all fitting data values. * @param values :: A vector of values for fitting. Must have the same size as * this. */ void FunctionValues::setFitData(const std::vector<double> &values) { if (values.size() != this->size()) { throw std::invalid_argument("Setting data of a wrong size"); } m_data.assign(values.begin(), values.end()); } /** * Get a fitting data value * @param i :: A value index */ double FunctionValues::getFitData(size_t i) const { if (m_data.size() != m_calculated.size()) { throw std::runtime_error("Fitting data was not set"); } return m_data[i]; } /** * Set a fitting weight * @param i :: A value index * @param value :: A new value for the weight. */ void FunctionValues::setFitWeight(size_t i, double value) { if (m_weights.size() != m_calculated.size()) { m_weights.resize(m_calculated.size()); } m_weights[i] = value; } /** * Set all fitting weights. * @param values :: A vector of fitting weights. Must have the same size as * this. */ void FunctionValues::setFitWeights(const std::vector<double> &values) { if (values.size() != this->size()) { throw std::invalid_argument("Setting data of a wrong size"); } m_weights.assign(values.begin(), values.end()); } /** * Set all weights to the same value. * @param value :: The value to set. */ void FunctionValues::setFitWeights(const double &value) { m_weights.resize(m_calculated.size(), value); } /** * Get a fitting weight. * @param i :: A value index. */ double FunctionValues::getFitWeight(size_t i) const { if (m_weights.size() != m_calculated.size()) { throw std::runtime_error("Fitting weights was not set"); } return m_weights[i]; } /** * Set fitting data copied from other FunctionValues' calculated values. * @param values :: An instance of FunctionValues to copy the data from. */ void FunctionValues::setFitDataFromCalculated(const FunctionValues &values) { m_data.assign(values.m_calculated.begin(), values.m_calculated.end()); } } // namespace API } // namespace Mantid