Как я могу использовать std :: valarray для хранения / манипулирования непрерывным 2D-массивом? - PullRequest
9 голосов
/ 02 февраля 2010

Как я могу использовать std::valarray для хранения / манипулирования 2D-массивом?

Я хотел бы увидеть пример 2D-массива с элементами, доступ к которым осуществляется по индексам строк / столбцов.Примерно такой псевдокод:

matrix(i,j) = 42;

Пример того, как инициализировать такой массив, тоже был бы хорош.Blitz ++.

Не стесняйтесь ответить, почему я не должен использовать valarray для моего варианта использования.Тем не менее, я хочу, чтобы память для многомерного массива была смежным (столбцы х строк) блоком.Нет вложенных массивов в стиле Java.

Ответы [ 4 ]

12 голосов
/ 03 февраля 2010

с макушки головы:

template <class element_type>
class matrix
{
public:
    matrix(size_t width, size_t height): m_stride(width), m_height(height), m_storage(width*height) {  }

    element_type &operator()(size_t row, size_t column)
    {
        // column major
        return m_storage[std::slice(column, m_height, m_stride)][row];

        // row major
        return m_storage[std::slice(row, m_stride, m_height)][column];
    }

private:
    std::valarray<element_type> m_storage;
    size_t m_stride;
    size_t m_height;
};

std::valarray предоставляет много интересных способов доступа к элементам через срезы, маски, многомерные срезы или таблицу косвенности. См. std::slice_array, std::gslice_array, std::mask_array и std::indirect_array для получения более подробной информации.

5 голосов
/ 03 февраля 2010
#include <iostream>
#include <valarray>

using namespace std;

typedef valarray<valarray<int> > va2d;

int main()
{
    int data[][3] = { {1, 2, 3}, {4, 5, 6} };
    va2d mat(valarray<int>(3), 2);
    for (int i = 0; i < 2; ++i)
    {
        for (int j = 0; j < 3; ++j)
           mat[ i ][ j ] = data[ i ][ j ];
    }
    for (int i = 0; i < 2; ++i)
        for (int j = 0; j < 3; ++j)
           cout << mat[ i ][ j ] << endl;
}

Подробнее о valarray:

  • Он оптимизирован для числовых вычислений.
  • Это контейнер типа vector со специальными функциями-членами для нарезки и нарезки кубиками..
  • Нет итераторов
  • Предназначен для векторных машин и плохо работает на текущих: vector доступ может быть быстрее
  • Не поддерживается всеми компиляторами (см. Документацию)/ плохо реализовано
  • См. 26.1 для типов, которые могут использоваться в качестве параметра для valarray<T>: Например:

3 Кроме того, многие члены и связанные с ними функцииvalarray может быть успешно создан и будет демонстрировать четко определенное поведение тогда и только тогда, когда T удовлетворяет дополнительным требованиям, указанным для каждого такого члена или связанной функции.

4 [Пример: создание экземпляра valarray допустимо, но оператор> () не будет успешно создан для операндов valarray, поскольку комплекс не имеет операторов упорядочения.- конец примера]

Редактировать # 2: Стандартные гарантии, что vector, как и массивы, всегда используют непрерывную память.Также у нас есть:

26.5.2 Шаблон класса valarray

1 Шаблон класса valarray - это одномерный смарт-массив, элементы которого нумеруются последовательно отнуль.Это представление математической концепции упорядоченного набора значений.Иллюзия более высокой размерности может быть вызвана знакомой идиомой вычисляемых индексов вместе с мощными возможностями поднабора, предоставляемыми обобщенными индексными операторами.

и далее:

26.5.2.3 доступ к элементу valarray

4 Аналогично, выражение & a [i]! = & B [j] оценивается как истинное для любых двух массивов a и b и для любых size_t i и size_tj такой, что i меньше длины a, а j меньше длины b.Это свойство указывает на отсутствие псевдонимов и может использоваться для оптимизации компиляторов.

0 голосов
/ 25 ноября 2017

Если вы хотите проверить, является ли многомерный массив непрерывным блоком (столбцы х строк). Вы можете увидеть этот пример с valarray .

template<class T>
class Array: public std::valarray<T> {
  size_t row,col; 
public:
  Array(){}
  Array(size_t nx) : std::valarray<T>(nx){row=nx,col=1;}
  Array(size_t nx, size_t ny) : std::valarray<T>(nx*ny){row=nx,col=ny;}
  virtual ~Array(){}
  T& operator()(size_t i,size_t j) { return (*this)[i*col+j];}
  size_t Size(size_t n) const { return (n<2) ? col: row;}
};
0 голосов
/ 03 февраля 2010

Вот пример, который включает немного матричной манипуляции

...