Окно перегородки с массивами наддува::интервалы


Мне нужно написать функцию, которая принимает поле в пространство, представленное как СТД::вектор наддува::интервалы, и разделить его на несколько небольших коробок. Во-первых, для удобства, я сделал некоторые определения

#include <iostream>
#include <boost/numeric/interval.hpp>
#include <vector>

namespace bn = boost::numeric;
namespace bi = bn::interval_lib;

// Interval typedefs
using Interval = bn::interval<
      double,
      bi::policies<
          bi::save_state<bi::rounded_transc_std<double> >,
          bi::checking_base<double>
      >
  >;

template<typename T> using array = std::vector<T>;

Затем, я беззастенчиво использовал код из этого и StackOverflow вопрос , который описывает, как достичь декартова произведения набора (вектора) наборов (векторов). Я превратил его в шаблон (для общности) примерно так:

template <class T>
class Combinator
{
public:
    Combinator(array<array<T>>& tsttors)
        : m_tsttors(tsttors)
    {
        m_combination.reserve(m_tsttors.size());
        for(auto& v : m_tsttors)
            m_combination.push_back(v.begin());
    }

    bool next() {
        // iterate through tsttors in reverse order
        for(int i = m_tsttors.size() - 1; i >= 0; --i) {
            array<T>& v = m_tsttors[i];
            typename array<T>::iterator& it = m_combination[i];

            if(++it != v.end())
                return true;
            it = v.begin();
        }
        return false;
    }

    array<typename array<T>::iterator> combination() const {
        return m_combination;
    }

private:
    array<array<T>>& m_tsttors; // reference to data
    array<typename array<T>::iterator> m_combination;
};

После этого я решил разделить каждый размер коробки (не фиксированного размера) в некоторое число n подынтервалов, а затем принять их декартово произведение, чтобы получить то, что я назвал сетку коробки. Я реализовал это так:

array<array<Interval>> box_grid(const array<Interval> &box, const int &parts){
    array<array<Interval>> splits;
    for(const auto& components : box) { // iterating through all box-dimensions
        const double &length = width(components);
        const double &start = components.lower();
        array<Interval> split_oned; // split each dimension

        for(int i = 0; i< parts; i++){ // evenly into "parts" parts
            Interval ival {start+ i*length/parts, start + (i+1)*length/parts};
            split_oned.push_back(ival);
        }
        splits.push_back(split_oned); // collect each split dimension
    }

    // and take their cartesian product for the boxes
    Combinator<Interval> combinator(splits);
    array<array<Interval>> box_array;
    do
    {
        const array<array<Interval>::iterator> combination = combinator.combination();
        array<Interval> single_box;
        for(const auto& it : combination){
            single_box.push_back(*it);
        }
        box_array.push_back(single_box);
    } while(combinator.next());

    return box_array;
}

Так как я новичок в C++ и не очень поднаторели в программировании в целом, я хотел бы иметь некоторую обратную связь и предложения по улучшению. Я буду использовать этот код для научных целей, поэтому производительность имеет решающее значение. Спасибо заранее.



96
1
задан 29 января 2018 в 11:01 Источник Поделиться
Комментарии