Program Listing for File misc.h

Return to documentation for file (include/amici/misc.h)

#ifndef AMICI_MISC_H
#define AMICI_MISC_H

#include "amici/defines.h"
#include "amici/exception.h"
#include "amici/vector.h"
#include <sunmatrix/sunmatrix_sparse.h> // SUNMatrixContent_Sparse

#include <algorithm>
#include <vector>
#include <memory>
#include <regex>
#include <functional>

#include <gsl/gsl-lite.hpp>

namespace amici {

template <class T>
gsl::span<T> slice(std::vector<T> &data, int index, unsigned size) {
    if ((index + 1) * size > data.size())
        throw std::out_of_range("requested slice is out of data range");
    if (size > 0)
        return gsl::make_span(&data.at(index*size), size);

    return gsl::make_span(static_cast<T*>(nullptr), 0);
}

template <class T>
gsl::span<const T> slice(const std::vector<T> &data,
                         int index, unsigned size) {
    if ((index + 1) * size > data.size())
        throw std::out_of_range("requested slice is out of data range");
    if (size > 0)
        return gsl::make_span(&data.at(index*size), size);

    return gsl::make_span(static_cast<T*>(nullptr), 0);
}

template <class T>
void checkBufferSize(gsl::span<T> buffer,
                     typename gsl::span<T>::index_type expected_size) {
    if (buffer.size() != expected_size)
        throw AmiException("Incorrect buffer size! Was %u, expected %u.",
                           buffer.size(), expected_size);
}

/* TODO: templating writeSlice breaks implicit conversion between vector & span
 not sure whether this is fixable */

template <class T>
void writeSlice(const gsl::span<const T> slice, gsl::span<T> buffer) {
    checkBufferSize(buffer, slice.size());
    std::copy(slice.begin(), slice.end(), buffer.data());
};

template <class T>
void addSlice(const gsl::span<const T> slice, gsl::span<T> buffer) {
    checkBufferSize(buffer, slice.size());
    std::transform(slice.begin(), slice.end(), buffer.begin(), buffer.begin(),
                   std::plus<T>());
};

template <class T>
void writeSlice(const std::vector<T> &s, std::vector<T> &b) {
    writeSlice(gsl::make_span(s.data(), s.size()),
               gsl::make_span(b.data(), b.size()));
};

template <class T>
void writeSlice(const std::vector<T> &s, gsl::span<T> b) {
    writeSlice(gsl::make_span(s.data(), s.size()), b);
};

template <class T>
void addSlice(const std::vector<T> &s, gsl::span<T> b) {
    addSlice(gsl::make_span(s.data(), s.size()), b);
};

void writeSlice(const AmiVector &s, gsl::span<realtype> b);


void unscaleParameters(gsl::span<const realtype> bufferScaled,
                       gsl::span<const ParameterScaling> pscale,
                       gsl::span<realtype> bufferUnscaled);

double getUnscaledParameter(double scaledParameter, ParameterScaling scaling);


double getScaledParameter(double unscaledParameter, ParameterScaling scaling);


void scaleParameters(gsl::span<const realtype> bufferUnscaled,
                     gsl::span<const ParameterScaling> pscale,
                     gsl::span<realtype> bufferScaled);

std::string backtraceString(int maxFrames);

std::string regexErrorToString(std::regex_constants::error_type err_type);

std::string printfToString(const char *fmt, va_list ap);

class ContextManager{
  public:
    ContextManager() = default;
    ContextManager(ContextManager &other) = delete;
    ContextManager(ContextManager &&other) = delete;
};


auto unravel_index(size_t flat_idx, size_t num_cols)
    -> std::pair<size_t, size_t>;

template <class T>
bool is_equal(T const& a, T const& b) {
    if(a.size() != b.size())
        return false;

    auto a_data = a.data();
    auto b_data = b.data();
    for(typename T::size_type i = 0; i < a.size(); ++i) {
        if(a_data[i] != b_data[i]
            && !(std::isnan(a_data[i]) && std::isnan(b_data[i])))
            return false;
    }
    return true;
}

} // namespace amici

#endif // AMICI_MISC_H