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 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
// Copyright (c) 2014 Stefan Walk
//
// This file is part of CGAL (www.cgal.org).
//
// $URL: https://github.com/CGAL/cgal/blob/v6.1.1/Classification/include/CGAL/Classification/ETHZ/internal/dataview.h $
// $Id: include/CGAL/Classification/ETHZ/internal/dataview.h 08b27d3db14 $
// SPDX-License-Identifier: LicenseRef-RFL
// License notice in Installation/LICENSE.RFL
//
// Author(s) : Stefan Walk
// Modifications from original library:
// * changed inclusion protection tag
// * moved to namespace CGAL::internal::
//
#ifndef CGAL_INTERNAL_LIBLEARNING_DATAVIEW_H
#define CGAL_INTERNAL_LIBLEARNING_DATAVIEW_H
#include <vector>
namespace CGAL { namespace internal {
namespace liblearning {
//! \brief A view for one-dimensional data
//
// The data can be e.g. a row or column of a matrix or the elements of an
// array or a std::vector - anything with a fixed step size between pointers
template <typename ElementType>
struct DataView1D {
//! \brief Element access
//
// \param idx the index of the element
ElementType& operator()(size_t idx) const
{
return *(data + step * idx);
}
//! \brief Construct using pointer, size and (optional) step size
DataView1D(ElementType* ptr, size_t size, ptrdiff_t step_size = 1) :
data(ptr), step(step_size), num_elements(size)
{
}
//! \brief Construct view from std::vector
//
// \param vec the vector, by-ref since we don't take ownership - no
// temporaries allowed. maybe needs to change
DataView1D(std::vector<ElementType>& vec) :
data(&vec[0]), step(1), num_elements(vec.size())
{
}
//! \brief Construct empty view
DataView1D() : data(0), step(1), num_elements(0)
{
}
ElementType* data; //!< Pointer to first element
ptrdiff_t step; //!< Step size between elements - for a vector this is 1, no need to multiply by sizeof(ElementType)
size_t num_elements; //!< Number of elements in the view
};
template <typename ElementType>
struct DataView2D {
//! \brief Construct empty view
DataView2D() : data(0), row_step(1), col_step(1), rows(0), cols(0)
{}
//! \brief Construct view from memory using given step sizes
DataView2D(ElementType* ptr, size_t rows_, size_t cols_, ptrdiff_t row_step_, ptrdiff_t col_step_) :
data(ptr), row_step(row_step_), col_step(col_step_), rows(rows_), cols(cols_)
{
}
//! \brief Construct view from a continuous block of memory in row-major order
DataView2D(ElementType* ptr, size_t rows_, size_t cols_) :
data(ptr), row_step(cols_), col_step(1), rows(rows_), cols(cols_)
{
}
//! \brief Element access
ElementType& operator()(size_t row_idx, size_t col_idx) const
{
return *(data + row_step * row_idx + col_step * col_idx);
}
//! \brief returns a 1D view of a row
DataView1D<ElementType> row(size_t row_idx)
{
return DataView1D<ElementType>(data + row_step * row_idx, cols, col_step);
}
//! \brief returns a 1D view of a column
DataView1D<ElementType> col(size_t col_idx)
{
return DataView1D<ElementType>(data + col_step * col_idx, rows, row_step);
}
//! \brief returns a new view, using a subset of rows
DataView2D row_range(size_t start_row, size_t end_row) const
{
DataView2D ret(*this);
ret.data = data + row_step * start_row;
ret.rows = end_row - start_row;
return ret;
}
//! \brief returns a new view, using a subset of columns
DataView2D col_range(size_t start_col, size_t end_col) const
{
DataView2D ret(*this);
ret.data = data + col_step * start_col;
ret.cols = end_col - start_col;
return ret;
}
//! \brief transposes the matrix (actually done by swapping the steps, no
// copying)
DataView2D transpose() const
{
DataView2D ret(*this);
std::swap(ret.row_step, ret.col_step);
std::swap(ret.rows, ret.cols);
return ret;
}
//! \brief Create a 2D view from a 1D one, represent as a column
static DataView2D column(DataView1D<ElementType> vec)
{
return DataView2D(vec.data, vec.num_elements, 1);
}
//! \brief Create a 2D view from a 1D one, represent as a row
static DataView2D row(DataView1D<ElementType> vec)
{
return DataView2D(vec.data, 1, vec.num_elements);
}
//! \brief returns the number of elements in this view
size_t num_elements() { return rows * cols; }
//! \brief returns true if the view is empty (no elements)
bool empty() { return num_elements() == 0; }
//! \brief returns true if rows in this view are continuous in memory
bool row_continuous() {
return col_step == 1;
}
//! \brief returns true if columns in this view are continuous in memory
bool col_continuous() {
return row_step == 1;
}
//! \brief gets pointer to row (only valid if row-continuous)
ElementType* row_pointer(size_t row_idx) {
return data + row_idx * row_step;
}
//! \brief gets pointer to column (only valid if column-continuous)
ElementType* col_pointer(size_t col_idx) {
return data + col_idx * col_step;
}
ElementType* data; //!< Pointer to first element
ptrdiff_t row_step; //!< Pointer difference between an element and its right neighbor - 1 if row-continuous
ptrdiff_t col_step; //!< Pointer difference between an element and its bottom neighbor - 1 if column-continuous
size_t rows; //!< Number of rows in the view
size_t cols; //!< Number of columns in the view
};
//! \brief determines if two 2D views have the same dimensions
template <typename A, typename B>
bool equal_dims(DataView2D<A> view_a, DataView2D<B> view_b)
{
return view_a.rows == view_b.rows && view_a.cols == view_b.cols;
}
}
}} // namespace CGAL::internal::
#endif
|