15 #ifndef BORNAGAIN_CORE_INTENSITY_LLDATA_H
16 #define BORNAGAIN_CORE_INTENSITY_LLDATA_H
31 LLData(
size_t rank,
const int* dimensions);
51 void setAll(
const T& value);
61 void allocate(
size_t rank,
const int* dimensions);
87 inline LLData<T>::LLData(
size_t rank,
const int* dimensions) : m_rank(0), m_dims(0), m_data_array(0)
107 if (
this != &right) {
116 return m_data_array[i];
121 return m_data_array[i];
126 return m_data_array[convertCoordinate(coordinate)];
131 return m_data_array[convertCoordinate(coordinate)];
138 "Operation += on LLData requires both operands to have the same dimensions");
139 for (
size_t i = 0; i < getTotalSize(); ++i) {
140 m_data_array[i] += right[i];
149 "Operation -= on LLData requires both operands to have the same dimensions");
150 for (
size_t i = 0; i < getTotalSize(); ++i) {
151 m_data_array[i] -= right[i];
160 "Operation *= on LLData requires both operands to have the same dimensions");
161 for (
size_t i = 0; i < getTotalSize(); ++i) {
162 m_data_array[i] *= right[i];
171 "Operation /= on LLData requires both operands to have the same dimensions");
172 for (
size_t i = 0; i < getTotalSize(); ++i) {
174 if (std::abs(m_data_array[i] - right[i])
175 <= std::numeric_limits<double>::epsilon() * std::abs(right[i])) {
177 }
else if (std::abs(right[i]) <= std::numeric_limits<double>::min()) {
178 ratio = double(m_data_array[i]) / std::numeric_limits<double>::min();
180 ratio = double(m_data_array[i] / right[i]);
182 m_data_array[i] = (T)ratio;
189 std::fill(m_data_array, m_data_array + getTotalSize(), value);
194 std::transform(m_data_array, m_data_array + getTotalSize(), m_data_array,
195 [&factor](
const T& value) -> T {
return value * factor; });
200 int result = std::accumulate(m_dims, m_dims + m_rank, 1, std::multiplies<int>{});
201 return static_cast<size_t>(result);
206 return std::accumulate(m_data_array, m_data_array + getTotalSize(), getZeroElement());
212 if (!checkDimensions(rank, dimensions)) {
213 throw std::runtime_error(
"LLData<T>::allocate error: dimensions must be > 0");
217 m_dims =
new int[m_rank];
218 std::copy(dimensions, dimensions + rank, m_dims);
219 m_data_array =
new T[getTotalSize()];
221 m_data_array =
new T[1];
229 delete[] m_data_array;
231 m_data_array =
nullptr;
234 delete[] m_data_array;
240 return std::all_of(dimensions, dimensions + rank,
241 [](
const int& dim) ->
bool {
return dim > 0; });
248 for (
size_t i = m_rank; i > 0; --i) {
249 result += offset * coordinate[i - 1];
250 offset *= m_dims[i - 1];
271 (*p_result) += right;
278 (*p_result) -= right;
285 (*p_result) *= right;
302 for (
size_t i = 0; i < left.
getRank(); ++i) {
303 if (ldims[i] != rdims[i])
Include to deal with Eigen alignment centrally.
Defines many exception classes in namespace Exceptionss.
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 * getDimensions() const
void setAll(const T &value)
void allocate(size_t rank, const int *dimensions)
void swapContents(LLData< T > &other)