matio-cpp  v0.2.5
A C++ wrapper of the matio library, with memory ownership handling, to read and write .mat files.
MultiDimensionalArray.tpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2020 Fondazione Istituto Italiano di Tecnologia
3  *
4  * This software may be modified and distributed under the terms of the
5  * BSD-2-Clause license (https://opensource.org/licenses/BSD-2-Clause).
6  */
7 
8 #ifndef MATIOCPP_MULTIDIMENSIONALARRAY_TPP
9 #define MATIOCPP_MULTIDIMENSIONALARRAY_TPP
10 
11 template<typename T>
12 bool matioCpp::MultiDimensionalArray<T>::checkCompatibility(const matvar_t* inputPtr, matioCpp::VariableType variableType, matioCpp::ValueType valueType) const
13 {
14 
15  if ((variableType != matioCpp::VariableType::MultiDimensionalArray) &&
16  (variableType != matioCpp::VariableType::Vector) &&
17  (variableType != matioCpp::VariableType::Element))
18  {
19  std::cerr << "[matioCpp::MultiDimensionalArray::checkCompatibility] The variable type is not compatible with a multidimensional array." << std::endl;
20  return false;
21  }
22 
23  if (inputPtr->isComplex)
24  {
25  std::cerr << "[matioCpp::MultiDimensionalArray::checkCompatibility] Cannot use a complex variable into a non-complex one." << std::endl;
26  return false;
27  }
28 
29  if (!matioCpp::is_convertible_to_primitive_type<T>(valueType))
30  {
31  std::string dataType = "";
32  std::string classType = "";
33 
34  get_types_names_from_matvart(inputPtr, classType, dataType);
35 
36  std::cerr << "[matioCpp::MultiDimensionalArray::checkCompatibility] The value type is not convertible to " <<
37  get_type<T>::toString() <<"." << std::endl <<
38  " Input class type: " << classType << std::endl <<
39  " Input data type: " << dataType << std::endl;
40  return false;
41  }
42  return true;
43 }
44 
45 template<typename T>
47 {
49  constexpr size_t emptyDimensions[] = {0, 0, 0};
50  initializeVariable("unnamed_multidimensional_array",
51  VariableType::MultiDimensionalArray,
52  matioCpp::get_type<T>::valueType(), emptyDimensions,
53  (void*)empty.data());
54 }
55 
56 template<typename T>
58 {
60  constexpr size_t emptyDimensions[] = {0, 0, 0};
61  initializeVariable(name,
62  VariableType::MultiDimensionalArray,
63  matioCpp::get_type<T>::valueType(), emptyDimensions,
64  (void*)empty.data());
65 }
66 
67 template<typename T>
69 {
72  {
73  if (dim == 0)
74  {
75  std::cerr << "[ERROR][matioCpp::MultiDimensionalArray::MultiDimensionalArray] Zero dimension detected." << std::endl;
76  assert(false);
77  }
78 
79  totalElements *= dim;
80  }
81 
83 
84  initializeVariable(name,
85  VariableType::MultiDimensionalArray,
87  (void*)dummy.data());
88 }
89 
90 template<typename T>
92 {
94  {
95  if (dim == 0)
96  {
97  std::cerr << "[ERROR][matioCpp::MultiDimensionalArray::MultiDimensionalArray] Zero dimension detected." << std::endl;
98  assert(false);
99  }
100  }
101 
102  initializeVariable(name,
103  VariableType::MultiDimensionalArray,
104  matioCpp::get_type<T>::valueType(), dimensions,
105  (void*)inputVector);
106 }
107 
108 template<typename T>
110 {
111  fromOther(other);
112 }
113 
114 template<typename T>
116 {
118 }
119 
120 template<typename T>
122  : matioCpp::Variable(handler)
123 {
124  if (!handler.get() || !checkCompatibility(handler.get(), handler.variableType(), handler.valueType()))
125  {
126  assert(false);
128  constexpr size_t emptyDimensions[] = {0, 0, 0};
129  initializeVariable("unnamed_multidimensional_array",
131  matioCpp::get_type<T>::valueType(), emptyDimensions,
132  (void*)empty.data());
133  }
134 }
135 
136 template<typename T>
138 {
139 
140 }
141 
142 template<typename T>
144 {
145  fromOther(other);
146  return *this;
147 }
148 
149 template<typename T>
151 {
153  return *this;
154 }
155 
156 template<typename T>
158 {
160  {
161  if (dim == 0)
162  {
163  std::cerr << "[ERROR][matioCpp::MultiDimensionalArray::fromVectorizedArray] Zero dimension detected." << std::endl;
164  return false;
165  }
166  }
167 
168  return initializeVariable(name(),
170  matioCpp::get_type<T>::valueType(), dimensions,
171  (void*)inputVector);
172 }
173 
174 template<typename T>
176 {
177  assert(dimensions().size() > 0 && numberOfElements() > 0 && "[matioCpp::MultiDimensionalArray::rawIndexFromIndices] The array is empty.");
178  assert(el.size() > 0 == dimensions().size() > 0 && "[matioCpp::MultiDimensionalArray::rawIndexFromIndices] The input vector el should have the same number of dimensions of the array.");
179  assert(el[0] < dimensions()[0] && "[matioCpp::MultiDimensionalArray::rawIndexFromIndices] The required element is out of bounds.");
180 
182  typename matioCpp::MultiDimensionalArray<T>::index_type previousDimensionsFactorial = 1;
183 
184  for (size_t i = 0; i < el.size(); ++i)
185  {
186  assert(el[i] < dimensions()[i] && "[matioCpp::MultiDimensionalArray::rawIndexFromIndices] The required element is out of bounds.");
187  index += el[i] * previousDimensionsFactorial;
188  previousDimensionsFactorial *= dimensions()[i];
189  }
190 
191  return index;
192 }
193 
194 template<typename T>
196 {
197  el.resize(dimensions().size());
198 
199  if (rawIndex >= numberOfElements())
200  {
201  std::cerr << "[ERROR][matioCpp::MultiDimensionalArray::indicesFromRawIndex] rawIndex is greater than the number of elements." << std::endl;
202  return false;
203  }
204 
205  typename matioCpp::MultiDimensionalArray<T>::index_type previousDimensionsFactorial = dimensions()[0];
206 
207  //First we fill el with the factorial of the dimensions
208 
209  for (size_t i = 1; i < el.size(); ++i)
210  {
211  el[i - 1] = previousDimensionsFactorial;
212  previousDimensionsFactorial *= dimensions()[i];
213  }
214 
215  typename matioCpp::MultiDimensionalArray<T>::index_type remainder = rawIndex;
216 
217  for (size_t i = el.size() - 1; i > 0; --i)
218  {
219  el[i] = remainder / el[i - 1];
220  remainder -= el[i] * el[i - 1];
221  }
222  el[0] = remainder;
223 
224  return true;
225 }
226 
227 template<typename T>
229 {
230  return matioCpp::make_span(data(), numberOfElements());
231 }
232 
233 template<typename T>
235 {
236  return matioCpp::make_span(data(), numberOfElements());
237 }
238 
239 template<typename T>
241 {
242  return changeName(newName);
243 }
244 
245 template<typename T>
247 {
249  for (matioCpp::MultiDimensionalArray<T>::index_type dim : newDimensions)
250  {
251  if (dim == 0)
252  {
253  std::cerr << "[ERROR][matioCpp::MultiDimensionalArray::resize] Zero dimension detected." << std::endl;
254  assert(false);
255  }
256 
257  totalElements *= dim;
258  }
259 
261 
262  initializeVariable(name(),
264  matioCpp::get_type<T>::valueType(), newDimensions,
265  dummy.data());
266 }
267 
268 template<typename T>
270 {
271  fromOther(std::move(MultiDimensionalArray<T>(name())));
272 }
273 
274 template<typename T>
276 {
277  return static_cast<typename matioCpp::MultiDimensionalArray<T>::pointer>(toMatio()->data);
278 }
279 
280 template<typename T>
282 {
283  return static_cast<typename matioCpp::MultiDimensionalArray<T>::const_pointer>(toMatio()->data);
284 }
285 
286 template<typename T>
288 {
289  return getArrayNumberOfElements();
290 }
291 
292 template<typename T>
294 {
295  return data()[rawIndexFromIndices(el)];
296 }
297 
298 template<typename T>
300 {
301  return data()[rawIndexFromIndices(el)];
302 }
303 
304 template<typename T>
306 {
307  assert(el < numberOfElements() && "[matioCpp::MultiDimensionalArray::operator()] The required element is out of bounds.");
308  return data()[el];
309 }
310 
311 template<typename T>
313 {
314  assert(el < numberOfElements() && "[matioCpp::MultiDimensionalArray::operator()] The required element is out of bounds.");
315  return data()[el];
316 }
317 
318 template<typename T>
320 {
321  return data()[rawIndexFromIndices(el)];
322 }
323 
324 template<typename T>
326 {
327  return data()[rawIndexFromIndices(el)];
328 }
329 
330 template<typename T>
332 {
333  assert(el < numberOfElements() && "[matioCpp::MultiDimensionalArray::operator[]] The required element is out of bounds.");
334  return data()[el];
335 }
336 
337 template<typename T>
339 {
340  assert(el < numberOfElements() && "[matioCpp::MultiDimensionalArray::operator[]] The required element is out of bounds.");
341  return data()[el];
342 }
343 
344 template<typename T>
346 {
347  return matioCpp::MultiDimensionalArray<T>(*m_handler);
348 }
349 
350 template<typename T>
352 {
353  return matioCpp::MultiDimensionalArray<T>(*m_handler);
354 }
355 
356 #endif // MATIOCPP_MULTIDIMENSIONALARRAY_TPP
ValueType valueType() const
Get the value type of the pointer.
virtual matvar_t * get() const =0
Get the shared matvar_t pointer.
VariableType variableType() const
Get the variable type of the pointer.
MultiDimensionalArray is a particular type of Variable specialized for multidimensional arrays of a g...
index_type numberOfElements() const
Get the total number of elements in the array.
reference operator[](const std::vector< index_type > &el)
Access specified element.
matioCpp::Span< element_type > toSpan()
Get this MultiDimensionalArray as a Span.
MultiDimensionalArray()
The const pointer type.
typename std::allocator_traits< std::allocator< element_type > >::const_pointer const_pointer
The pointer type.
MultiDimensionalArray< T > & operator=(const MultiDimensionalArray< T > &other)
Assignement operator (copy) from another MultiDimensionalArray.
bool setName(const std::string &newName)
Change the name of the Variable.
bool fromVectorizedArray(const std::vector< index_type > &dimensions, const_pointer inputVector)
Set from a vectorized array.
bool indicesFromRawIndex(size_t rawIndex, std::vector< index_type > &el) const
Get the indices given the raw index.
reference operator()(const std::vector< index_type > &el)
Access specified element.
void clear()
Clear the multidimensional array.
void resize(const std::vector< index_type > &newDimensions)
Resize the vector.
pointer data()
Direct access to the underlying array.
size_t index_type
Defines how to allocate T.
typename std::allocator_traits< std::allocator< element_type > >::pointer pointer
The reference type.
element_type & reference
The type used for indices.
std::remove_cv_t< element_type > value_type
Defines the type of an element of the MultiDimensionalArray.
index_type rawIndexFromIndices(const std::vector< index_type > &el) const
Get the index in the vectorized array corresponding to the provided indices.
The matioCpp::Variable class is the equivalent of matvar_t in matio.
Definition: Variable.h:23
matioCpp::MultiDimensionalArray< T > asMultiDimensionalArray()
Cast the variable as a MultiDimensionalArray.
bool initializeVariable(const std::string &name, const VariableType &variableType, const ValueType &valueType, matioCpp::Span< const size_t > dimensions, void *data)
Initialize the variable.
Definition: Variable.cpp:16
T data(T... args)
T endl(T... args)
T forward(T... args)
T move(T... args)
MATIOCPP_CONSTEXPR Span< ElementType > make_span(ElementType *ptr, typename Span< ElementType >::index_type count)
Definition: Span.h:714
VariableType
Define the type of variable.
ValueType
The list of types for an element of a certain variable type.
bool get_types_names_from_matvart(const matvar_t *input, std::string &classType, std::string &dataType)
Get the type names from the input pointer.
Utility metafunction to get the ValueType from a given primitive type.