16 #error no need to expose this header to Swig
20 #ifndef BORNAGAIN_DEVICE_DATA_LLDATA_H
21 #define BORNAGAIN_DEVICE_DATA_LLDATA_H
54 void setAll(
const T& value);
90 inline LLData<T>::LLData(
size_t rank,
const int* dimensions) : m_rank(0), m_dims(0), m_data_array(0)
110 if (
this != &right) {
119 return m_data_array[i];
124 return m_data_array[i];
129 return m_data_array[convertCoordinate(coordinate)];
134 return m_data_array[convertCoordinate(coordinate)];
140 throw std::runtime_error(
141 "Operation += on LLData requires both operands to have the same dimensions");
142 for (
size_t i = 0; i < getTotalSize(); ++i) {
143 m_data_array[i] += right[i];
151 throw std::runtime_error(
152 "Operation -= on LLData requires both operands to have the same dimensions");
153 for (
size_t i = 0; i < getTotalSize(); ++i) {
154 m_data_array[i] -= right[i];
162 throw std::runtime_error(
163 "Operation *= on LLData requires both operands to have the same dimensions");
164 for (
size_t i = 0; i < getTotalSize(); ++i) {
165 m_data_array[i] *= right[i];
173 throw std::runtime_error(
174 "Operation /= on LLData requires both operands to have the same dimensions");
175 for (
size_t i = 0; i < getTotalSize(); ++i) {
177 if (std::abs(m_data_array[i] - right[i])
178 <= std::numeric_limits<double>::epsilon() * std::abs(right[i])) {
180 }
else if (std::abs(right[i]) <= std::numeric_limits<double>::min()) {
181 ratio = double(m_data_array[i]) / std::numeric_limits<double>::min();
183 ratio = double(m_data_array[i] / right[i]);
185 m_data_array[i] = (T)ratio;
192 std::fill(m_data_array, m_data_array + getTotalSize(), value);
197 std::transform(m_data_array, m_data_array + getTotalSize(), m_data_array,
198 [&factor](
const T& value) -> T {
return value * factor; });
203 int result = std::accumulate(m_dims, m_dims + m_rank, 1, std::multiplies<int>{});
204 return static_cast<size_t>(result);
209 return std::accumulate(m_data_array, m_data_array + getTotalSize(), getZeroElement());
215 if (!checkDimensions(rank, dimensions)) {
216 throw std::runtime_error(
"LLData<T>::allocate error: dimensions must be > 0");
220 m_dims =
new int[m_rank];
221 std::copy(dimensions, dimensions + rank, m_dims);
222 m_data_array =
new T[getTotalSize()];
224 m_data_array =
new T[1];
232 delete[] m_data_array;
234 m_data_array =
nullptr;
237 delete[] m_data_array;
243 return std::all_of(dimensions, dimensions + rank,
244 [](
const int& dim) ->
bool {
return dim > 0; });
251 for (
size_t i = m_rank; i > 0; --i) {
252 result += offset * coordinate[i - 1];
253 offset *= m_dims[i - 1];
274 (*p_result) += right;
281 (*p_result) -= right;
288 (*p_result) *= right;
305 for (
size_t i = 0; i < left.
rank(); ++i) {
306 if (ldims[i] != rdims[i])
Include to deal with Eigen alignment centrally.
bool HaveSameDimensions(const LLData< T > &left, const LLData< T > &right)
void swap(OutputDataIterator< TValue, TContainer > &left, OutputDataIterator< TValue, TContainer > &right)
make Swappable
BasicVector3D< T > operator+(const BasicVector3D< T > &v)
Unary plus.
auto operator*(const BasicVector3D< T > &v, const U a)
Multiplication vector by scalar.
BasicVector3D< T > operator/(const BasicVector3D< T > &v, U a)
Division vector by scalar.
BasicVector3D< T > operator-(const BasicVector3D< T > &v)
Unary minus.
Template class to store data of any type in multi-dimensional space (low-level).
size_t convertCoordinate(int *coordinate) const
LLData< T > & operator=(const LLData< T > &right)
LLData< T > & operator/=(const LLData< T > &right)
LLData< T > & operator*=(const LLData< T > &right)
LLData< T > & operator-=(const LLData< T > &right)
T & atCoordinate(int *coordinate)
LLData< double > meanValues() const
LLData(size_t rank, const int *dimensions)
void scaleAll(const T &factor)
LLData< T > & operator+=(const LLData< T > &right)
bool checkDimensions(size_t rank, const int *dimensions) const
size_t getTotalSize() const
const int * dimensions() const
void setAll(const T &value)
void allocate(size_t rank, const int *dimensions)
void swapContents(LLData< T > &other)