This file is indexed.

/usr/include/libwildmagic/Wm5Matrix3.h is in libwildmagic-dev 5.13-1ubuntu3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
// Geometric Tools, LLC
// Copyright (c) 1998-2014
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
// http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
//
// File Version: 5.0.1 (2010/10/01)

#ifndef WM5MATRIX3_H
#define WM5MATRIX3_H

// The (x,y,z) coordinate system is assumed to be right-handed.  Coordinate
// axis rotation matrices are of the form
//   RX =    1       0       0
//           0     cos(t) -sin(t)
//           0     sin(t)  cos(t)
// where t > 0 indicates a counterclockwise rotation in the yz-plane
//   RY =  cos(t)    0     sin(t)
//           0       1       0
//        -sin(t)    0     cos(t)
// where t > 0 indicates a counterclockwise rotation in the zx-plane
//   RZ =  cos(t) -sin(t)    0
//         sin(t)  cos(t)    0
//           0       0       1
// where t > 0 indicates a counterclockwise rotation in the xy-plane.

#include "Wm5MathematicsLIB.h"
#include "Wm5Table.h"
#include "Wm5Vector3.h"
#include "Wm5SingularValueDecomposition.h"

namespace Wm5
{

template <typename Real>
class Matrix3 : public Table<3,3,Real>
{
public:
    // If makeZero is 'true', create the zero matrix; otherwise, create the
    // identity matrix.
    Matrix3 (bool makeZero = true);

    // Copy constructor.
    Matrix3 (const Matrix3& mat);

    // Input mrc is in row r, column c.
    Matrix3 (Real m00, Real m01, Real m02, Real m10, Real m11, Real m12,
        Real m20, Real m21, Real m22);

    // Create a matrix from an array of numbers.  The input array is
    // interpreted based on the bool input as
    //   true:  entry[0..8]={m00,m01,m02,m10,m11,m12,m20,m21,m22} [row major]
    //   false: entry[0..8]={m00,m10,m20,m01,m11,m21,m02,m12,m22} [col major]
    Matrix3 (const Real entry[9], bool rowMajor);

    // Create matrices based on vector input.  The bool is interpreted as
    //   true: vectors are columns of the matrix
    //   false: vectors are rows of the matrix
    Matrix3 (const Vector3<Real>& u, const Vector3<Real>& v,
        const Vector3<Real>& w, bool columns);
    Matrix3 (const Vector3<Real>* v, bool columns);

    // Create a diagonal matrix, m01 = m10 = m02 = m20 = m12 = m21 = 0.
    Matrix3 (Real m00, Real m11, Real m22);

    // Create rotation matrices (positive angle -> counterclockwise).  The
    // angle must be in radians, not degrees.
    Matrix3 (const Vector3<Real>& axis, Real angle);

    // Create a tensor product U*V^T.
    Matrix3 (const Vector3<Real>& u, const Vector3<Real>& v);

    // Assignment.
    Matrix3& operator= (const Matrix3& mat);

    // Create various matrices.
    Matrix3& MakeZero ();
    Matrix3& MakeIdentity ();
    Matrix3& MakeDiagonal (Real m00, Real m11, Real m22);
    Matrix3& MakeRotation (const Vector3<Real>& axis, Real angle);
    Matrix3& MakeTensorProduct (const Vector3<Real>& u,
        const Vector3<Real>& v);

    // Arithmetic operations.
    Matrix3 operator+ (const Matrix3& mat) const;
    Matrix3 operator- (const Matrix3& mat) const;
    Matrix3 operator* (Real scalar) const;
    Matrix3 operator/ (Real scalar) const;
    Matrix3 operator- () const;

    // Arithmetic updates.
    Matrix3& operator+= (const Matrix3& mat);
    Matrix3& operator-= (const Matrix3& mat);
    Matrix3& operator*= (Real scalar);
    Matrix3& operator/= (Real scalar);

    // M*vec
    Vector3<Real> operator* (const Vector3<Real>& vec) const;

    // u^T*M*v
    Real QForm (const Vector3<Real>& u, const Vector3<Real>& v) const;

    // M^T
    Matrix3 Transpose () const;

    // M*mat
    Matrix3 operator* (const Matrix3& mat) const;

    // M^T*mat
    Matrix3 TransposeTimes (const Matrix3& mat) const;

    // M*mat^T
    Matrix3 TimesTranspose (const Matrix3& mat) const;

    // M^T*mat^T
    Matrix3 TransposeTimesTranspose (const Matrix3& mat) const;

    // Other operations.
    Matrix3 TimesDiagonal (const Vector3<Real>& diag) const;  // M*D
    Matrix3 DiagonalTimes (const Vector3<Real>& diag) const;  // D*M
    Matrix3 Inverse (const Real epsilon = (Real)0) const;
    Matrix3 Adjoint () const;
    Real Determinant () const;

    // The matrix must be a rotation for these functions to be valid.  The
    // last function uses Gram-Schmidt orthonormalization applied to the
    // columns of the rotation matrix.  The angle must be in radians, not
    // degrees.
    void ExtractAxisAngle (Vector3<Real>& axis, Real& angle) const;
    void Orthonormalize ();

    // The matrix must be symmetric.  Factor M = R * D * R^T where
    // R = [u0|u1|u2] is a rotation matrix with columns u0, u1, and u2 and
    // D = diag(d0,d1,d2) is a diagonal matrix whose diagonal entries are d0,
    // d1, and d2.  The eigenvector u[i] corresponds to eigenvector d[i].
    // The eigenvalues are ordered as d0 <= d1 <= d2.
    void EigenDecomposition (Matrix3& rot, Matrix3& diag) const;

    // Create rotation matrices from Euler angles.
    void MakeEulerXYZ (Real xAngle, Real yAngle, Real zAngle);
    void MakeEulerXZY (Real xAngle, Real zAngle, Real yAngle);
    void MakeEulerYXZ (Real yAngle, Real xAngle, Real zAngle);
    void MakeEulerYZX (Real yAngle, Real zAngle, Real xAngle);
    void MakeEulerZXY (Real zAngle, Real xAngle, Real yAngle);
    void MakeEulerZYX (Real zAngle, Real yAngle, Real xAngle);
    void MakeEulerXYX (Real x0Angle, Real yAngle, Real x1Angle);
    void MakeEulerXZX (Real x0Angle, Real zAngle, Real x1Angle);
    void MakeEulerYXY (Real y0Angle, Real xAngle, Real y1Angle);
    void MakeEulerYZY (Real y0Angle, Real zAngle, Real y1Angle);
    void MakeEulerZXZ (Real z0Angle, Real xAngle, Real z1Angle);
    void MakeEulerZYZ (Real z0Angle, Real yAngle, Real z1Angle);

    // Extract Euler angles from rotation matrices.
    enum EulerResult
    {
        // The solution is unique.
        EA_UNIQUE,

        // The solution is not unique.  A sum of angles is constant.
        EA_NOT_UNIQUE_SUM,

        // The solution is not unique.  A difference of angles is constant.
        EA_NOT_UNIQUE_DIF
    };

    // The return values are in the specified ranges:
    //   xAngle in [-pi,pi], yAngle in [-pi/2,pi/2], zAngle in [-pi,pi]
    // When the solution is not unique, zAngle = 0 is returned.  Generally,
    // the set of solutions is
    //   EA_NOT_UNIQUE_SUM:  zAngle + xAngle = c
    //   EA_NOT_UNIQUE_DIF:  zAngle - xAngle = c
    // for some angle c.
    EulerResult ExtractEulerXYZ (Real& xAngle, Real& yAngle, Real& zAngle)
        const;

    // The return values are in the specified ranges:
    //   xAngle in [-pi,pi], zAngle in [-pi/2,pi/2], yAngle in [-pi,pi]
    // When the solution is not unique, yAngle = 0 is returned.  Generally,
    // the set of solutions is
    //   EA_NOT_UNIQUE_SUM:  yAngle + xAngle = c
    //   EA_NOT_UNIQUE_DIF:  yAngle - xAngle = c
    // for some angle c.
    EulerResult ExtractEulerXZY (Real& xAngle, Real& zAngle, Real& yAngle)
        const;

    // The return values are in the specified ranges:
    //   yAngle in [-pi,pi], xAngle in [-pi/2,pi/2], zAngle in [-pi,pi]
    // When the solution is not unique, zAngle = 0 is returned.  Generally,
    // the set of solutions is
    //   EA_NOT_UNIQUE_SUM:  zAngle + yAngle = c
    //   EA_NOT_UNIQUE_DIF:  zAngle - yAngle = c
    // for some angle c.
    EulerResult ExtractEulerYXZ (Real& yAngle, Real& xAngle, Real& zAngle)
        const;

    // The return values are in the specified ranges:
    //   yAngle in [-pi,pi], zAngle in [-pi/2,pi/2], xAngle in [-pi,pi]
    // When the solution is not unique, xAngle = 0 is returned.  Generally,
    // the set of solutions is
    //   EA_NOT_UNIQUE_SUM:  xAngle + yAngle = c
    //   EA_NOT_UNIQUE_DIF:  xAngle - yAngle = c
    // for some angle c.
    EulerResult ExtractEulerYZX (Real& yAngle, Real& zAngle, Real& xAngle)
        const;

    // The return values are in the specified ranges:
    //   zAngle in [-pi,pi], xAngle in [-pi/2,pi/2], yAngle in [-pi,pi]
    // When the solution is not unique, yAngle = 0 is returned.  Generally,
    // the set of solutions is
    //   EA_NOT_UNIQUE_SUM:  yAngle + zAngle = c
    //   EA_NOT_UNIQUE_DIF:  yAngle - zAngle = c
    // for some angle c.
    EulerResult ExtractEulerZXY (Real& zAngle, Real& xAngle, Real& yAngle)
        const;

    // The return values are in the specified ranges:
    //   zAngle in [-pi,pi], yAngle in [-pi/2,pi/2], xAngle in [-pi,pi]
    // When the solution is not unique, xAngle = 0 is/ returned.  Generally,
    // the set of solutions is
    //   EA_NOT_UNIQUE_SUM:  xAngle + zAngle = c
    //   EA_NOT_UNIQUE_DIF:  xAngle - zAngle = c
    // for some angle c.
    EulerResult ExtractEulerZYX (Real& zAngle, Real& yAngle, Real& xAngle)
        const;

    // The return values are in the specified ranges:
    //   x0Angle in [-pi,pi], yAngle in [0,pi], x1Angle in [-pi,pi]
    // When the solution is not unique, x1Angle = 0 is returned.  Generally,
    // the set of solutions is
    //   EA_NOT_UNIQUE_SUM:  x1Angle + x0Angle = c
    //   EA_NOT_UNIQUE_DIF:  x1Angle - x0Angle = c
    // for some angle c.
    EulerResult ExtractEulerXYX (Real& x0Angle, Real& yAngle, Real& x1Angle)
        const;

    // The return values are in the specified ranges:
    //   x0Angle in [-pi,pi], zAngle in [0,pi], x1Angle in [-pi,pi]
    // When the solution is not unique, x1Angle = 0 is returned.  Generally,
    // the set of solutions is
    //   EA_NOT_UNIQUE_SUM:  x1Angle + x0Angle = c
    //   EA_NOT_UNIQUE_DIF:  x1Angle - x0Angle = c
    // for some angle c.
    EulerResult ExtractEulerXZX (Real& x0Angle, Real& zAngle, Real& x1Angle)
        const;

    // The return values are in the specified ranges:
    //   y0Angle in [-pi,pi], xAngle in [0,pi], y1Angle in [-pi,pi]
    // When the solution is not unique, y1Angle = 0 is returned.  Generally,
    // the set of solutions is
    //   EA_NOT_UNIQUE_SUM:  y1Angle + y0Angle = c
    //   EA_NOT_UNIQUE_DIF:  y1Angle - y0Angle = c
    // for some angle c.
    EulerResult ExtractEulerYXY (Real& y0Angle, Real& xAngle, Real& y1Angle)
        const;

    // The return values are in the specified ranges:
    //   y0Angle in [-pi,pi], zAngle in [0,pi], y1Angle in [-pi,pi]
    // When the solution is not unique, y1Angle = 0 is returned.  Generally,
    // the set of solutions is
    //   EA_NOT_UNIQUE_SUM:  y1Angle + y0Angle = c
    //   EA_NOT_UNIQUE_DIF:  y1Angle - y0Angle = c
    // for some angle c.
    EulerResult ExtractEulerYZY (Real& y0Angle, Real& zAngle, Real& y1Angle)
        const;

    // The return values are in the specified ranges:
    //   z0Angle in [-pi,pi], xAngle in [0,pi], z1Angle in [-pi,pi]
    // When the solution is not unique, z1Angle = 0 is returned.  Generally,
    // the set of solutions is
    //   EA_NOT_UNIQUE_SUM:  z1Angle + z0Angle = c
    //   EA_NOT_UNIQUE_DIF:  z1Angle - z0Angle = c
    // for some angle c.
    EulerResult ExtractEulerZXZ (Real& z0Angle, Real& xAngle, Real& z1Angle)
        const;

    // The return values are in the specified ranges:
    //   z0Angle in [-pi,pi], yAngle in [0,pi], z1Angle in [-pi,pi]
    // When the solution is not unique, z1Angle = 0 is returned.  Generally,
    // the set of solutions is
    //   EA_NOT_UNIQUE_SUM:  z1Angle + z0Angle = c
    //   EA_NOT_UNIQUE_DIF:  z1Angle - z0Angle = c
    // for some angle c.
    EulerResult ExtractEulerZYZ (Real& z0Angle, Real& yAngle, Real& z1Angle)
        const;

    // SLERP (spherical linear interpolation) without quaternions.  Computes
    // R(t) = R0*(Transpose(R0)*R1)^t.  If Q is a rotation matrix with
    // unit-length axis U and angle A, then Q^t is a rotation matrix with
    // unit-length axis U and rotation angle t*A.
    Matrix3& Slerp (Real t, const Matrix3& rot0, const Matrix3& rot1);

    // Singular value decomposition, M = L*D*Transpose(R), where L and R are
    // orthogonal and D is a diagonal matrix whose diagonal entries are
    // nonnegative.
    void SingularValueDecomposition (Matrix3& left, Matrix3& diag,
        Matrix3& rightTranspose) const;

    // Polar decomposition, M = Q*S, where Q is orthogonal and S is symmetric.
    // This uses the singular value decomposition:
    //   M = L*D*Transpose(R) = (L*Transpose(R))*(R*D*Transpose(R)) = Q*S
    // where Q = L*Transpose(R) and S = R*D*Transpose(R).
    void PolarDecomposition (Matrix3& qMat, Matrix3& sMat);

    // Factor M = Q*D*U with orthogonal Q, diagonal D, upper triangular U.
    void QDUDecomposition (Matrix3& qMat, Matrix3& diag, Matrix3& uMat)
        const;

    // Special matrices.
    WM5_MATHEMATICS_ITEM static const Matrix3 ZERO;
    WM5_MATHEMATICS_ITEM static const Matrix3 IDENTITY;

private:
    // Support for eigendecomposition.  The Tridiagonalize function applies
    // a Householder transformation to the matrix.  If that transformation
    // is the identity (the matrix is already tridiagonal), then the return
    // value is 'false'.  Otherwise, the transformation is a reflection and
    // the return value is 'true'.  The QLAlgorithm returns 'true' iff the
    // QL iteration scheme converged.
    bool Tridiagonalize (Real diagonal[3], Real subdiagonal[2]);
    bool QLAlgorithm (Real diagonal[3], Real subdiagonal[2]);

protected:
    using Table<3,3,Real>::mEntry;
};

// c * M
template <typename Real>
inline Matrix3<Real> operator* (Real scalar, const Matrix3<Real>& mat);

// v^T * M
template <typename Real>
inline Vector3<Real> operator* (const Vector3<Real>& vec,
    const Matrix3<Real>& mat);

#include "Wm5Matrix3.inl"

typedef Matrix3<float> Matrix3f;
typedef Matrix3<double> Matrix3d;

}

#endif