cisst-saw
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cmnDataFunctionsMatrixHelpers.h
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */
3 
4 /*
5 
6  Author(s): Anton Deguet
7  Created on: 2012-07-09
8 
9  (C) Copyright 2012-2013 Johns Hopkins University (JHU), All Rights
10  Reserved.
11 
12 --- begin cisst license - do not edit ---
13 
14 This software is provided "as is" under an open source license, with
15 no warranty. The complete license can be found in license.txt and
16 http://www.cisst.org/cisst/license.txt.
17 
18 --- end cisst license ---
19 
20 */
21 
22 #pragma once
23 
24 #ifndef _cmnDataFunctionsMatrixHelpers_h
25 #define _cmnDataFunctionsMatrixHelpers_h
26 
27 template <class _matrixType>
28 void cmnDataMatrixCopy(_matrixType & data,
29  const _matrixType & source)
30 {
31  // resize destination if needed
32  data.resize(source.size());
33  typedef _matrixType MatrixType;
34  typedef typename MatrixType::iterator iterator;
35  typedef typename MatrixType::const_iterator const_iterator;
36  const const_iterator endSource = source.end();
37  const_iterator iterSource = source.begin();
38  iterator iterData = data.begin();
39  for (;
40  iterSource != endSource;
41  ++iterSource, ++iterData) {
43  }
44 }
45 
46 template <class _matrixType>
47 std::string cmnDataMatrixHumanReadable(const _matrixType & data)
48 {
49  std::stringstream stringStream;
50  const size_t rows = data.rows();
51  const size_t cols = data.cols();
52  stringStream << "[";
53  for (size_t row = 0; row < rows; ++row) {
54  if (row != 0) {
55  stringStream << ", ";
56  }
57  stringStream << "[";
58  for (size_t col = 0; col < cols; ++col) {
59  if (col != 0) {
60  stringStream << ", ";
61  }
62  stringStream << cmnData<typename _matrixType::value_type>::HumanReadable(data.at(row, col));
63  }
64  stringStream << "]";
65  }
66  stringStream << "]";
67  return stringStream.str();
68 }
69 
70 template <class _matrixType>
71 void cmnDataMatrixSerializeText(const _matrixType & data,
72  std::ostream & outputStream,
73  const char delimiter)
74  throw (std::runtime_error)
75 {
76  typedef typename _matrixType::const_iterator const_iterator;
77  const const_iterator begin = data.begin();
78  const const_iterator end = data.end();
79  for (const_iterator iter = begin; iter != end; ++iter) {
80  if (iter != begin) {
81  outputStream << delimiter;
82  }
83  cmnData<typename _matrixType::value_type>::SerializeText(*iter, outputStream, delimiter);
84  }
85 }
86 
87 template <class _matrixType>
88 void cmnDataMatrixDeSerializeText(_matrixType & data,
89  std::istream & inputStream,
90  const char delimiter)
91 {
92  // get data
93  typedef typename _matrixType::iterator iterator;
94  const iterator begin = data.begin();
95  const iterator end = data.end();
96  for (iterator iter = begin; iter != end; ++iter) {
97  if (iter != begin) {
98  cmnDataDeSerializeTextDelimiter(inputStream, delimiter, "std::matrix");
99  }
100  cmnData<typename _matrixType::value_type>::DeSerializeText(*iter, inputStream, delimiter);
101  }
102 }
103 
104 template <class _matrixType>
105 void cmnDataMatrixDeSerializeTextResize(_matrixType & data,
106  std::istream & inputStream,
107  const char delimiter)
108  throw (std::runtime_error)
109 {
110  // deserialize size
111  size_t rows, cols;
112  cmnData<size_t>::DeSerializeText(rows, inputStream, delimiter);
113  cmnDataDeSerializeTextDelimiter(inputStream, delimiter, "vctFixedSizeMatrixBase");
114  cmnData<size_t>::DeSerializeText(cols, inputStream, delimiter);
115  data.resize(rows, cols);
116  if (data.size() > 0) {
117  cmnDataDeSerializeTextDelimiter(inputStream, delimiter, "vctFixedSizeMatrixBase");
118  cmnDataMatrixDeSerializeText(data, inputStream, delimiter);
119  }
120 }
121 
122 template <class _matrixType>
124  std::istream & inputStream,
125  const char delimiter)
126  throw (std::runtime_error)
127 {
128  // deserialize size
129  size_t rows, cols;
130  cmnData<size_t>::DeSerializeText(rows, inputStream, delimiter);
131  cmnDataDeSerializeTextDelimiter(inputStream, delimiter, "vctFixedSizeMatrixBase");
132  cmnData<size_t>::DeSerializeText(cols, inputStream, delimiter);
133  if ((data.rows() != rows) || (data.cols() != cols)) {
134  cmnThrow("cmnDataDeSerializeText: matrix size doesn't match");
135  return;
136  }
137  if (data.size() > 0) {
138  cmnDataDeSerializeTextDelimiter(inputStream, delimiter, "vctFixedSizeMatrixBase");
139  cmnDataMatrixDeSerializeText(data, inputStream, delimiter);
140  }
141 }
142 
143 template <class _matrixType>
144 std::string cmnDataMatrixSerializeDescription(const _matrixType & data,
145  const char delimiter,
146  const std::string & userDescription,
147  const bool serializeSize)
148 {
149  std::string prefix = (userDescription == "") ? "m[" : (userDescription + "[");
150  std::stringstream indexSuffix;
151  std::stringstream description;
152  const size_t rows = data.rows();
153  const size_t cols = data.cols();
154  if (serializeSize) {
155  description << cmnData<size_t>::SerializeDescription(rows, delimiter, (userDescription == "") ? "v.rows" : (userDescription + ".rows"))
156  << delimiter
157  << cmnData<size_t>::SerializeDescription(cols, delimiter, (userDescription == "") ? "v.cols" : (userDescription + ".cols"));
158  }
159  size_t row, col;
160  for (row = 0; row < rows; ++row) {
161  for (col = 0; col < cols; ++col) {
162  if ((row + col) != 0 || serializeSize) {
163  description << delimiter;
164  }
165  indexSuffix.clear();
166  indexSuffix.str(std::string());
167  indexSuffix << row << "," << col << "]";
168  description << cmnData<typename _matrixType::value_type>::SerializeDescription(data.Element(row, col), delimiter, prefix + indexSuffix.str());
169  }
170  }
171  return description.str();
172 }
173 
174 template <class _matrixType>
175 void cmnDataMatrixSerializeBinary(const _matrixType & data,
176  std::ostream & outputStream)
177  throw (std::runtime_error)
178 {
179  typedef typename _matrixType::const_iterator const_iterator;
180  const const_iterator end = data.end();
181  const_iterator iter = data.begin();
182  for (; iter != end; ++iter) {
184  }
185 }
186 
187 template <class _matrixType>
188 void cmnDataMatrixDeSerializeBinary(_matrixType & data,
189  std::istream & inputStream,
190  const cmnDataFormat & localFormat,
191  const cmnDataFormat & remoteFormat)
192  throw (std::runtime_error)
193 {
194  // deserialize data
195  typedef typename _matrixType::iterator iterator;
196  const iterator end = data.end();
197  iterator iter = data.begin();
198  for (; iter != end; ++iter) {
199  cmnData<typename _matrixType::value_type>::DeSerializeBinary(*iter, inputStream, localFormat, remoteFormat);
200  }
201 }
202 
203 template <class _matrixType>
204 void cmnDataMatrixDeSerializeBinaryResize(_matrixType & data,
205  std::istream & inputStream,
206  const cmnDataFormat & localFormat,
207  const cmnDataFormat & remoteFormat)
208  throw (std::runtime_error)
209 {
210  // deserialize size and resize
211  size_t rows, cols;
212  cmnDataDeSerializeBinary_size_t(rows, inputStream, localFormat, remoteFormat);
213  cmnDataDeSerializeBinary_size_t(cols, inputStream, localFormat, remoteFormat);
214  data.resize(rows, cols);
215  cmnDataMatrixDeSerializeBinary(data, inputStream, localFormat, remoteFormat);
216 }
217 
218 template <class _matrixType>
220  std::istream & inputStream,
221  const cmnDataFormat & localFormat,
222  const cmnDataFormat & remoteFormat)
223  throw (std::runtime_error)
224 {
225  // deserialize size and check
226  size_t rows, cols;
227  cmnDataDeSerializeBinary_size_t(rows, inputStream, localFormat, remoteFormat);
228  cmnDataDeSerializeBinary_size_t(cols, inputStream, localFormat, remoteFormat);
229  if ((data.rows() != rows)
230  || (data.cols() != cols)) {
231  cmnThrow("cmnDataDeSerializeBinary: matrix size doesn't match");
232  return;
233  }
234  cmnDataMatrixDeSerializeBinary(data, inputStream, localFormat, remoteFormat);
235 }
236 
237 template <class _matrixType>
238 size_t cmnDataMatrixScalarNumber(const _matrixType & data, const bool includeSize)
239 {
240  size_t result = includeSize ? 2 : 0;
241  typedef typename _matrixType::value_type value_type;
242  if (cmnData<value_type>::ScalarNumberIsFixed(data.Element(0, 0))) {
243  return result + data.size() * cmnData<value_type>::ScalarNumber(data.Element(0, 0));
244  }
245  typedef typename _matrixType::const_iterator const_iterator;
246  const const_iterator end = data.end();
247  const_iterator iter = data.begin();
248  for (; iter != end; ++iter) {
249  result += cmnData<value_type>::ScalarNumber(*iter);
250  }
251  return result;
252 }
253 
254 template <class _matrixType>
255 bool cmnDataMatrixScalarFindInMatrixIndex(const _matrixType & data, const size_t index,
256  size_t & elementRow, size_t & elementCol, size_t & inElementIndex)
257 {
258  typedef typename _matrixType::value_type value_type;
259  size_t elementIndex;
260  const size_t scalarNumber = cmnDataMatrixScalarNumber(data, false);
261  if (cmnData<value_type>::ScalarNumberIsFixed(data.Element(0, 0))) {
262  const size_t scalarNumberPerElement = cmnData<value_type>::ScalarNumber(data.Element(0, 0));
263  if (scalarNumberPerElement == 0) {
264  return false;
265  }
266  if (index < scalarNumber) {
267  elementIndex = index / scalarNumberPerElement;
268  inElementIndex = index % scalarNumberPerElement;
269  elementRow = elementIndex / data.cols();
270  elementCol = elementIndex % data.cols();
271  return true;
272  }
273  return false;
274  }
275 
276  bool indexFound = false;
277  size_t scalarCounter = 0;
278  size_t lastScalarInElement = 0;
279  size_t firstScalarInElement = 0;
280  size_t numberOfScalarsInElement = 0;
281  elementIndex = 0;
282  do {
283  elementRow = elementIndex / data.cols();
284  elementCol = elementIndex % data.cols(); ;
285  numberOfScalarsInElement = cmnData<value_type>::ScalarNumber(data.Element(elementRow, elementCol));
286  firstScalarInElement = scalarCounter;
287  lastScalarInElement = scalarCounter + numberOfScalarsInElement - 1;
288  scalarCounter = lastScalarInElement + 1;
289  elementIndex++;
290  indexFound = ((index >= firstScalarInElement) && (index <= lastScalarInElement));
291  } while ((!indexFound)
292  && (elementIndex < data.size()));
293  if (indexFound) {
294  elementIndex--;
295  inElementIndex = index - firstScalarInElement;
296  return true;
297  }
298  return false;
299 }
300 
301 template <class _matrixType>
302 std::string cmnDataMatrixScalarDescription(const _matrixType & data,
303  const size_t index,
304  const std::string & userDescription,
305  const bool includeSize)
306  throw (std::out_of_range)
307 {
308  size_t elementRow, elementCol, inElementIndex;
309  size_t realIndex = index;
310  std::stringstream suffix;
311  if (includeSize) {
312  if (index == 0) {
313  return cmnData<size_t>::ScalarDescription(data.rows(), 0, userDescription + ".rows");
314  }
315  if (index == 1) {
316  return cmnData<size_t>::ScalarDescription(data.cols(), 0, userDescription + ".cols");
317  }
318  realIndex -= 2;
319  }
320  if (cmnDataMatrixScalarFindInMatrixIndex(data, realIndex, elementRow, elementCol, inElementIndex)) {
321  suffix << "[" << elementRow << ',' << elementCol << "]";
322  return cmnData<typename _matrixType::value_type>::ScalarDescription(data.Element(elementRow, elementCol), inElementIndex, userDescription + suffix.str());
323  }
324  cmnThrow(std::out_of_range("cmnDataScalarDescription: matrix index out of range"));
325  return "";
326 }
327 
328 template <class _matrixType>
329 double cmnDataMatrixScalar(const _matrixType & data, const size_t index, const bool includeSize)
330  throw (std::out_of_range)
331 {
332  size_t elementRow, elementCol, inElementIndex;
333  size_t realIndex = index;
334  if (includeSize) {
335  if (index == 0) {
336  return static_cast<double>(data.rows());
337  }
338  if (index == 1) {
339  return static_cast<double>(data.cols());
340  }
341  realIndex -= 2;
342  }
343  if (cmnDataMatrixScalarFindInMatrixIndex(data, realIndex, elementRow, elementCol, inElementIndex)) {
344  return cmnData<typename _matrixType::value_type>::Scalar(data.Element(elementRow, elementCol), inElementIndex);
345  } else {
346  cmnThrow(std::out_of_range("cmnDataScalar: matrix index out of range"));
347  }
348  return 0.123456789; // unreachable, just to avoid compiler warnings
349 }
350 
351 #endif // _cmnDataFunctionsMatrixHelpers_h
void cmnDataMatrixSerializeText(const _matrixType &data, std::ostream &outputStream, const char delimiter)
Definition: cmnDataFunctionsMatrixHelpers.h:71
double cmnDataMatrixScalar(const _matrixType &data, const size_t index, const bool includeSize)
Definition: cmnDataFunctionsMatrixHelpers.h:329
Definition: cmnDataFormat.h:32
void cmnDataMatrixDeSerializeBinary(_matrixType &data, std::istream &inputStream, const cmnDataFormat &localFormat, const cmnDataFormat &remoteFormat)
Definition: cmnDataFunctionsMatrixHelpers.h:188
size_t CISST_EXPORT cmnDataDeSerializeBinary_size_t(size_t &data, const char *buffer, size_t bufferSize, const cmnDataFormat &localFormat, const cmnDataFormat &remoteFormat)
static void SerializeBinary(const DataType &data, std::ostream &outputStream)
void cmnDataMatrixDeSerializeBinaryCheckSize(_matrixType &data, std::istream &inputStream, const cmnDataFormat &localFormat, const cmnDataFormat &remoteFormat)
Definition: cmnDataFunctionsMatrixHelpers.h:219
static void SerializeText(const DataType &data, std::ostream &outputStream, const char delimiter= ',')
void cmnDataMatrixDeSerializeText(_matrixType &data, std::istream &inputStream, const char delimiter)
Definition: cmnDataFunctionsMatrixHelpers.h:88
bool cmnDataMatrixScalarFindInMatrixIndex(const _matrixType &data, const size_t index, size_t &elementRow, size_t &elementCol, size_t &inElementIndex)
Definition: cmnDataFunctionsMatrixHelpers.h:255
void cmnDataMatrixSerializeBinary(const _matrixType &data, std::ostream &outputStream)
Definition: cmnDataFunctionsMatrixHelpers.h:175
void cmnDataMatrixDeSerializeTextCheckSize(_matrixType &data, std::istream &inputStream, const char delimiter)
Definition: cmnDataFunctionsMatrixHelpers.h:123
std::string cmnDataMatrixHumanReadable(const _matrixType &data)
Definition: cmnDataFunctionsMatrixHelpers.h:47
static size_t ScalarNumber(const DataType &data)
static double Scalar(const DataType &data, const size_t index)
Definition: cmnDataFunctions.h:53
static std::string ScalarDescription(const DataType &data, const size_t index, const std::string &userDescription="")
#define cmnThrow(a)
Definition: MinimalCmn.h:4
void cmnDataMatrixDeSerializeTextResize(_matrixType &data, std::istream &inputStream, const char delimiter)
Definition: cmnDataFunctionsMatrixHelpers.h:105
void cmnDataMatrixDeSerializeBinaryResize(_matrixType &data, std::istream &inputStream, const cmnDataFormat &localFormat, const cmnDataFormat &remoteFormat)
Definition: cmnDataFunctionsMatrixHelpers.h:204
std::string cmnDataMatrixSerializeDescription(const _matrixType &data, const char delimiter, const std::string &userDescription, const bool serializeSize)
Definition: cmnDataFunctionsMatrixHelpers.h:144
static void DeSerializeText(DataType &data, std::istream &inputStream, const char delimiter= ',')
void cmnDataMatrixCopy(_matrixType &data, const _matrixType &source)
Definition: cmnDataFunctionsMatrixHelpers.h:28
static void DeSerializeBinary(DataType &data, std::istream &inputStream, const cmnDataFormat &localFormat, const cmnDataFormat &remoteFormat)
std::string cmnDataMatrixScalarDescription(const _matrixType &data, const size_t index, const std::string &userDescription, const bool includeSize)
Definition: cmnDataFunctionsMatrixHelpers.h:302
static void Copy(DataType &data, const DataType &source)
size_t cmnDataMatrixScalarNumber(const _matrixType &data, const bool includeSize)
Definition: cmnDataFunctionsMatrixHelpers.h:238
void CISST_EXPORT cmnDataDeSerializeTextDelimiter(std::istream &inputStream, const char delimiter, const char *className)