xsmatrix.c
Go to the documentation of this file.
1 
2 // Copyright (c) 2003-2021 Xsens Technologies B.V. or subsidiaries worldwide.
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions, and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions, and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the names of the copyright holders nor the names of their contributors
16 // may be used to endorse or promote products derived from this software without
17 // specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
24 // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR
26 // TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.THE LAWS OF THE NETHERLANDS
28 // SHALL BE EXCLUSIVELY APPLICABLE AND ANY DISPUTES SHALL BE FINALLY SETTLED UNDER THE RULES
29 // OF ARBITRATION OF THE INTERNATIONAL CHAMBER OF COMMERCE IN THE HAGUE BY ONE OR MORE
30 // ARBITRATORS APPOINTED IN ACCORDANCE WITH SAID RULES.
31 //
32 
33 
34 // Copyright (c) 2003-2021 Xsens Technologies B.V. or subsidiaries worldwide.
35 // All rights reserved.
36 //
37 // Redistribution and use in source and binary forms, with or without modification,
38 // are permitted provided that the following conditions are met:
39 //
40 // 1. Redistributions of source code must retain the above copyright notice,
41 // this list of conditions, and the following disclaimer.
42 //
43 // 2. Redistributions in binary form must reproduce the above copyright notice,
44 // this list of conditions, and the following disclaimer in the documentation
45 // and/or other materials provided with the distribution.
46 //
47 // 3. Neither the names of the copyright holders nor the names of their contributors
48 // may be used to endorse or promote products derived from this software without
49 // specific prior written permission.
50 //
51 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
52 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
53 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
54 // THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 // SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
56 // OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR
58 // TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.THE LAWS OF THE NETHERLANDS
60 // SHALL BE EXCLUSIVELY APPLICABLE AND ANY DISPUTES SHALL BE FINALLY SETTLED UNDER THE RULES
61 // OF ARBITRATION OF THE INTERNATIONAL CHAMBER OF COMMERCE IN THE HAGUE BY ONE OR MORE
62 // ARBITRATORS APPOINTED IN ACCORDANCE WITH SAID RULES.
63 //
64 
65 #include "xsmatrix.h"
66 #include <stdlib.h>
67 #include <math.h>
68 #include "xsdebugcounters.h"
69 #include <string.h>
70 #include "xsmalloc.h"
71 #include "xsquaternion.h"
72 #include <assert.h>
73 
74 #ifdef __ICCARM__
75  #pragma diag_suppress=Pa039
76 #endif
77 
87 void XsMatrix_ref(XsMatrix* thisPtr, XsSize rows, XsSize cols, XsSize stride, XsReal* buffer, XsDataFlags flags)
88 {
89  //assert(!(thisPtr->m_flags & XSDF_FixedSize));
90  //XsMatrix_destruct(thisPtr);
91 
92  *((XsReal**) &thisPtr->m_data) = buffer;
93  *((XsSize*) &thisPtr->m_flags) = (XsSize) flags;
94  *((XsSize*) &thisPtr->m_rows) = rows;
95  *((XsSize*) &thisPtr->m_cols) = cols;
96  *((XsSize*) &thisPtr->m_stride) = stride;
97 }
98 
100 void XsMatrix_construct(XsMatrix* thisPtr, XsSize rows, XsSize cols, XsSize stride, const XsReal* src, XsSize srcStride)
101 {
102  XsSize r;
103  XsSize size = rows * stride;
104 
105  if (stride == 0)
106  {
107  stride = cols;
108  size = rows * stride;
109  }
110  if (size)
111  {
112  // init to size
113  XsReal* data = (XsReal*) xsMathMalloc(size * sizeof(XsReal));
114  assert(data);
115  *((XsReal**) &thisPtr->m_data) = data;
117  }
118  else
119  *((XsReal**) &thisPtr->m_data) = 0;
120  *((XsSize*) &thisPtr->m_flags) = XSDF_Managed;
121  *((XsSize*) &thisPtr->m_rows) = rows;
122  *((XsSize*) &thisPtr->m_cols) = cols;
123  *((XsSize*) &thisPtr->m_stride) = stride;
124 
125  if (src && size)
126  {
127  if (srcStride == 0 || srcStride == stride)
128  memcpy(thisPtr->m_data, src, size * sizeof(XsReal));
129  else
130  {
131  for (r = 0; r < rows; ++r)
132  {
133 #if XSREAL_ALLOWS_MEMCPY
134  memcpy(thisPtr->m_data + r * stride, src + r * srcStride, cols * sizeof(XsReal));
135 #else
136  XsSize c;
137  for (c = 0; c < cols; ++c)
138  thisPtr->m_data[r * stride + c] = src[r * srcStride + c];
139 #endif
140  }
141  }
142  }
143 }
144 
146 void XsMatrix_assign(XsMatrix* thisPtr, XsSize rows, XsSize cols, XsSize stride, const XsReal* src, XsSize srcStride)
147 {
148  XsSize r;
149  XsSize size = rows * stride;
150 
151  if (thisPtr->m_flags & XSDF_FixedSize)
152  {
153  if (rows == 0 && cols == 0)
154  {
155  *((XsSize*) &thisPtr->m_flags) |= XSDF_Empty;
156  return;
157  }
158 
159  assert(thisPtr->m_rows == rows && thisPtr->m_cols == cols);
160  stride = thisPtr->m_stride;
161  size = thisPtr->m_rows * stride;
162  *((XsSize*) &thisPtr->m_flags) &= ~XSDF_Empty;
163  }
164  else
165  {
166  if (thisPtr->m_rows == rows && thisPtr->m_cols == cols &&
167  (stride == 0 || stride == thisPtr->m_stride))
168  {
169  stride = thisPtr->m_stride;
170  size = rows * stride;
171  }
172  else
173  {
174  if (stride == 0)
175  {
176  stride = cols;
177  size = rows * stride;
178  }
179  if (size > thisPtr->m_rows * thisPtr->m_stride || thisPtr->m_rows == 0)
180  {
181  XsMatrix_destruct(thisPtr);
182  if (size)
183  {
184  // init to size
185  XsReal* data = (XsReal*) xsMathMalloc(size * sizeof(XsReal));
186  assert(data);
187  *((XsReal**) &thisPtr->m_data) = data;
188  *((XsSize*) &thisPtr->m_flags) = XSDF_Managed;
190  }
191  }
192  *((XsSize*) &thisPtr->m_rows) = rows;
193  *((XsSize*) &thisPtr->m_cols) = cols;
194  *((XsSize*) &thisPtr->m_stride) = stride;
195  }
196  }
197  if (src && size)
198  {
199  if (stride == cols && (srcStride == 0 || srcStride == stride))
200  memcpy(thisPtr->m_data, src, size * sizeof(XsReal));
201  else
202  {
203  for (r = 0; r < rows; ++r)
204  {
205 #if XSREAL_ALLOWS_MEMCPY
206  memcpy(thisPtr->m_data + r * stride, src + r * srcStride, cols * sizeof(XsReal));
207 #else
208  XsSize c;
209  for (c = 0; c < cols; ++c)
210  thisPtr->m_data[r * stride + c] = src[r * srcStride + c];
211 #endif
212  }
213  }
214  }
215 }
216 
219 {
220  if (thisPtr->m_data && (thisPtr->m_flags & XSDF_Managed))
221  {
222  // clear contents
223  xsMathFree((void*) thisPtr->m_data);
225  }
226  // init to 0
227  if (!(thisPtr->m_flags & XSDF_FixedSize))
228  {
229  *((XsReal**) &thisPtr->m_data) = 0;
230  *((XsSize*) &thisPtr->m_rows) = 0;
231  *((XsSize*) &thisPtr->m_cols) = 0;
232  *((XsSize*) &thisPtr->m_stride) = 0;
233  *((XsSize*) &thisPtr->m_flags) = 0;
234  }
235  else
236  *((XsSize*) &thisPtr->m_flags) |= XSDF_Empty;
237 }
238 
240 void XsMatrix_copy(XsMatrix* copy, XsMatrix const* src)
241 {
242  if (copy == src)
243  return;
244  XsMatrix_assign(copy, src->m_rows, src->m_cols, 0, src->m_data, src->m_stride);
245 }
246 
249 {
250 #if XSREAL_ALLOWS_MEMCPY
251  if (thisPtr->m_stride == thisPtr->m_cols)
252  memset(thisPtr->m_data, 0, sizeof(XsReal)*thisPtr->m_rows * thisPtr->m_cols);
253  else
254  {
255  XsSize r;
256  for (r = 0; r < thisPtr->m_rows; ++r)
257  memset(thisPtr->m_data + r * thisPtr->m_stride, 0, sizeof(XsReal) * thisPtr->m_cols);
258  }
259 #else
260  XsSize r, c, stride = thisPtr->m_stride;
261  for (r = 0; r < thisPtr->m_rows; ++r)
262  for (c = 0; c < thisPtr->m_cols; ++c)
263  thisPtr->m_data[r * stride + c] = XsMath_zero;
264 #endif
265 }
266 
268 int XsMatrix_empty(const XsMatrix* thisPtr)
269 {
270  return (thisPtr->m_rows == 0) || (thisPtr->m_cols == 0) || (thisPtr->m_flags & XSDF_Empty);
271 }
272 
277 void XsMatrix_multiplyScalar(const XsMatrix* thisPtr, XsReal scalar, XsMatrix* dest)
278 {
279  XsSize r, c, stride = thisPtr->m_stride, stride2;
280  XsMatrix_assign(dest, thisPtr->m_rows, thisPtr->m_cols, 0, 0, 0);
281  stride2 = dest->m_stride;
282  for (r = 0; r < thisPtr->m_rows; ++r)
283  for (c = 0; c < thisPtr->m_cols; ++c)
284  dest->m_data[r * stride2 + c] = thisPtr->m_data[r * stride + c] * scalar;
285 }
286 
293 XsSize XsMatrix_offset(const XsMatrix* thisPtr, XsSize row, XsSize column)
294 {
295  return XsMatrix_offsetM(thisPtr, row, column);
296 }
297 
299 XsReal XsMatrix_value(const XsMatrix* thisPtr, XsSize row, XsSize column)
300 {
301  return thisPtr->m_data[XsMatrix_offsetM(thisPtr, row, column)];
302 }
303 
304 
306 void XsMatrix_setValue(XsMatrix* thisPtr, XsSize row, XsSize column, XsReal value)
307 {
308  thisPtr->m_data[XsMatrix_offsetM(thisPtr, row, column)] = value;
309 }
310 
312 int XsMatrix_dimensionsMatch(const XsMatrix* thisPtr, XsSize rows, XsSize columns)
313 {
314  return thisPtr->m_rows == rows && thisPtr->m_cols == columns;
315 }
316 
318 void XsMatrix_fromQuaternion(XsMatrix* thisPtr, const XsQuaternion* quat)
319 {
320  XsReal q00, q11, q22, q33, q01, q02, q03, q12, q13, q23;
321 
322  if (XsQuaternion_empty(quat))
323  {
324  XsMatrix_destruct(thisPtr);
325  return;
326  }
327 
328  q00 = quat->m_w * quat->m_w;
329  q11 = quat->m_x * quat->m_x;
330  q22 = quat->m_y * quat->m_y;
331  q33 = quat->m_z * quat->m_z;
332 
333  q01 = quat->m_w * quat->m_x;
334  q02 = quat->m_w * quat->m_y;
335  q03 = quat->m_w * quat->m_z;
336 
337  q12 = quat->m_x * quat->m_y;
338  q13 = quat->m_x * quat->m_z;
339  q23 = quat->m_y * quat->m_z;
340 
341  XsMatrix_assign(thisPtr, 3, 3, 3, 0, 0);
342 
343  XsMatrix_setValue(thisPtr, 0, 0, (q00 + q11 - q22) - q33);
344  XsMatrix_setValue(thisPtr, 0, 1, (q12 - q03) * XsMath_two);
345  XsMatrix_setValue(thisPtr, 0, 2, (q13 + q02) * XsMath_two);
346 
347  XsMatrix_setValue(thisPtr, 1, 0, (q12 + q03) * XsMath_two);
348  XsMatrix_setValue(thisPtr, 1, 1, (q00 - q11) + (q22 - q33));
349  XsMatrix_setValue(thisPtr, 1, 2, (q23 - q01) * XsMath_two);
350 
351  XsMatrix_setValue(thisPtr, 2, 0, (q13 - q02) * XsMath_two);
352  XsMatrix_setValue(thisPtr, 2, 1, (q23 + q01) * XsMath_two);
353  XsMatrix_setValue(thisPtr, 2, 2, ((q00 - q11) - q22) + q33);
354 }
355 
363 {
364 #ifdef __ICCARM__
365 #pragma diag_suppress=Pe370
366 #endif
367  XsMatrix tmp;
368  if ((!a->m_data || (a->m_flags & XSDF_Managed)) && (!b->m_data || (b->m_flags & XSDF_Managed)))
369  {
370  *((XsReal**) &tmp.m_data) = a->m_data;
371  *((XsSize*) &tmp.m_rows) = a->m_rows;
372  *((XsSize*) &tmp.m_cols) = a->m_cols;
373  *((XsSize*) &tmp.m_stride) = a->m_stride;
374  *((XsSize*) &tmp.m_flags) = a->m_flags;
375 
376  *((XsReal**) &a->m_data) = b->m_data;
377  *((XsSize*) &a->m_rows) = b->m_rows;
378  *((XsSize*) &a->m_cols) = b->m_cols;
379  *((XsSize*) &a->m_stride) = b->m_stride;
380  *((XsSize*) &a->m_flags) = b->m_flags;
381 
382  *((XsReal**) &b->m_data) = tmp.m_data;
383  *((XsSize*) &b->m_rows) = tmp.m_rows;
384  *((XsSize*) &b->m_cols) = tmp.m_cols;
385  *((XsSize*) &b->m_stride) = tmp.m_stride;
386  *((XsSize*) &b->m_flags) = tmp.m_flags;
387  }
388  else
389  {
390  XsSize r, c;
391  XsReal v;
392  assert(a->m_data && b->m_data && a->m_rows == b->m_rows && a->m_cols == b->m_cols);
393  for (r = 0; r < a->m_rows; ++r)
394  {
395  XsReal* aa = a->m_data + r * a->m_stride;
396  XsReal* bb = b->m_data + r * b->m_stride;
397  for (c = 0; c < a->m_cols; ++c, ++aa, ++bb)
398  {
399  v = *aa;
400  *aa = *bb;
401  *bb = v;
402  }
403  }
404  }
405 }
406 
XsMatrix::XsMatrix_swap
void XsMatrix_swap(XsMatrix *a, XsMatrix *b)
Swap the contents of a and b.
Definition: xsmatrix.c:362
XsMatrix::XsMatrix_ref
void XsMatrix_ref(XsMatrix *thisPtr, XsSize rows, XsSize cols, XsSize stride, XsReal *buffer, XsDataFlags flags)
Construct the XsMatrix as a reference to data in buffer.
Definition: xsmatrix.c:87
XsMatrix
A class that represents a matrix of real numbers.
Definition: xsmatrix.h:107
XsMatrix::XsMatrix_destruct
void XsMatrix_destruct(XsMatrix *thisPtr)
Clear the XsMatrix and release allocated resources.
Definition: xsmatrix.c:218
XsMatrix::XsMatrix_setZero
void XsMatrix_setZero(XsMatrix *thisPtr)
Set all the values in the matrix to zero.
Definition: xsmatrix.c:248
XsMatrix::XsMatrix_value
XsReal XsMatrix_value(const XsMatrix *thisPtr, XsSize row, XsSize column)
Returns the data value at row and column.
Definition: xsmatrix.c:299
xsquaternion.h
XsMatrix::XsMatrix_copy
void XsMatrix_copy(XsMatrix *copy, XsMatrix const *src)
Copy the contents of copy to the XsMatrix.
Definition: xsmatrix.c:240
XsMatrix::XsMatrix_empty
int XsMatrix_empty(const XsMatrix *thisPtr)
Returns not zero if the matrix contains no values.
Definition: xsmatrix.c:268
XSDF_FixedSize
@ XSDF_FixedSize
The contained data points to a fixed-size buffer, this allows creation of dynamic objects on the stac...
Definition: xstypedefs.h:111
XsMatrix::XsMatrix_dimensionsMatch
int XsMatrix_dimensionsMatch(const XsMatrix *thisPtr, XsSize rows, XsSize columns)
Returns not zero if the dimensions of the XsMatrix are equal to rows and columns.
Definition: xsmatrix.c:312
XsQuaternion
A class that implements a quaternion.
Definition: xsquaternion.h:102
xsmalloc.h
data
data
xsmatrix.h
XsMatrix::m_rows
const XsSize m_rows
Number of rows in the matrix.
Definition: xsmatrix.h:111
XsQuaternion::XsQuaternion_empty
int XsQuaternion_empty(const XsQuaternion *thisPtr)
Test if this is a null object.
Definition: xsquaternion.c:94
XsMatrix::XsMatrix_offset
XsSize XsMatrix_offset(const XsMatrix *thisPtr, XsSize row, XsSize column)
Returns the offset in the data for accessing the value at row and column.
Definition: xsmatrix.c:293
xsMathMalloc
#define xsMathMalloc(n)
Definition: xsmalloc.h:84
xsdebugcounters.h
XsMatrix::XsMatrix_setValue
void XsMatrix_setValue(XsMatrix *thisPtr, XsSize row, XsSize column, XsReal value)
Sets the data value at row and column.
Definition: xsmatrix.c:306
XsMatrix::m_data
XSCPPPROTECTED XsReal *const m_data
Contained data.
Definition: xsmatrix.h:110
XsMatrix_offsetM
#define XsMatrix_offsetM(thisPtr, row, column)
Definition: xsmatrix.h:99
XsMatrix_incFreeCount
static int XsMatrix_incFreeCount(void)
Definition: xsdebugcounters.h:136
XsReal
double XsReal
Defines the floating point type used by the Xsens libraries.
Definition: xstypedefs.h:73
XsSize
size_t XsSize
XsSize must be unsigned number!
Definition: xstypedefs.h:74
XsQuaternion::m_x
XsReal m_x
Stores the x component of the quaternion.
Definition: xsquaternion.h:110
XsMatrix::XsMatrix_construct
void XsMatrix_construct(XsMatrix *thisPtr, XsSize rows, XsSize cols, XsSize stride, const XsReal *src, XsSize srcStride)
Init the XsMatrix and copy the data from src into the matrix if src is not null.
Definition: xsmatrix.c:100
xsMathFree
#define xsMathFree(p)
Definition: xsmalloc.h:92
XsMatrix::m_cols
const XsSize m_cols
Number of columns in the matrix.
Definition: xsmatrix.h:112
XSDF_Empty
@ XSDF_Empty
The object contains undefined data / should be considered empty. Usually only relevant when XSDF_Fixe...
Definition: xstypedefs.h:112
XsMatrix_incAllocCount
static int XsMatrix_incAllocCount(void)
Definition: xsdebugcounters.h:132
XsMath_two
XSMATHCONST XsReal XsMath_two
2
Definition: xsmath.h:162
XsMath_zero
XSMATHCONST XsReal XsMath_zero
0
Definition: xsmath.h:150
XsMatrix::m_stride
const XsSize m_stride
Number of items per row in memory (usually equal to cols but not always)
Definition: xsmatrix.h:113
XsMatrix::XsMatrix_assign
void XsMatrix_assign(XsMatrix *thisPtr, XsSize rows, XsSize cols, XsSize stride, const XsReal *src, XsSize srcStride)
Init the XsMatrix and copy the data from src into the matrix if src is not null.
Definition: xsmatrix.c:146
XsMatrix::XsMatrix_fromQuaternion
void XsMatrix_fromQuaternion(XsMatrix *thisPtr, const XsQuaternion *quat)
Get an orientation matrix representation of the quaternion.
Definition: xsmatrix.c:318
XsDataFlags
XsDataFlags
These flags define the behaviour of data contained by Xsens data structures.
Definition: xstypedefs.h:107
XsQuaternion::m_y
XsReal m_y
Stores the y component of the quaternion.
Definition: xsquaternion.h:111
XSDF_Managed
@ XSDF_Managed
The contained data should be managed (freed) by the object, when false, the object assumes the memory...
Definition: xstypedefs.h:110
XsQuaternion::m_w
XsReal m_w
Stores the w component of the quaternion.
Definition: xsquaternion.h:109
assert.h
XsMatrix::XsMatrix_multiplyScalar
void XsMatrix_multiplyScalar(const XsMatrix *thisPtr, XsReal scalar, XsMatrix *dest)
Multiplies all values in this XsMatrix by scalar.
Definition: xsmatrix.c:277
XsQuaternion::m_z
XsReal m_z
Stores the z component of the quaternion.
Definition: xsquaternion.h:112
XsMatrix::m_flags
const XsSize m_flags
Flags for data management.
Definition: xsmatrix.h:114


xsens_mti_driver
Author(s):
autogenerated on Sun Sep 3 2023 02:43:20