// @(#)root/smatrix:$Id$
// Author: L. Moneta, J. Palacios    2006

#ifndef ROOT_Math_MatrixRepresentationsStatic
#define ROOT_Math_MatrixRepresentationsStatic 1

// Include files

/**
@defgroup MatRep SMatrix Storage Representation
@ingroup SMatrixGroup

@author Juan Palacios
@date   2006-01-15

Classes MatRepStd and MatRepSym for generic and symmetric matrix
data storage and manipulation. Define data storage and access, plus
operators =, +=, -=, ==.

*/

#ifndef ROOT_Math_StaticCheck
#include "Math/StaticCheck.h"
#endif

#include <cstddef>
#include <utility>
#include <type_traits>
#include <array>

namespace ROOT {

namespace Math {

//________________________________________________________________________________
/**
MatRepStd
Standard Matrix representation for a general D1 x D2 matrix.
This class is itself a template on the contained type T, the number of rows and the number of columns.
Its data member is an array T[nrows*ncols] containing the matrix data.
The data are stored in the row-major C convention.
For example, for a matrix, M, of size 3x3, the data \f$\left[a_0,a_1,a_2,.......,a_7,a_8 \right] \f$d are stored in the following order:
\f[
M = \left( \begin{array}{ccc}
a_0 & a_1 & a_2  \\
a_3 & a_4  & a_5  \\
a_6 & a_7  & a_8   \end{array} \right)
\f]

@ingroup MatRep
*/

template <class T, unsigned int D1, unsigned int D2=D1>
class MatRepStd {

public:

typedef T  value_type;

inline const T& operator()(unsigned int i, unsigned int j) const {
return fArray[i*D2+j];
}
inline T& operator()(unsigned int i, unsigned int j) {
return fArray[i*D2+j];
}
inline T& operator[](unsigned int i) { return fArray[i]; }

inline const T& operator[](unsigned int i) const { return fArray[i]; }

inline T apply(unsigned int i) const { return fArray[i]; }

inline T* Array() { return fArray; }

inline const T* Array() const { return fArray; }

template <class R>
inline MatRepStd<T, D1, D2>& operator+=(const R& rhs) {
for(unsigned int i=0; i<kSize; ++i) fArray[i] += rhs[i];
return *this;
}

template <class R>
inline MatRepStd<T, D1, D2>& operator-=(const R& rhs) {
for(unsigned int i=0; i<kSize; ++i) fArray[i] -= rhs[i];
return *this;
}

template <class R>
inline MatRepStd<T, D1, D2>& operator=(const R& rhs) {
for(unsigned int i=0; i<kSize; ++i) fArray[i] = rhs[i];
return *this;
}

template <class R>
inline bool operator==(const R& rhs) const {
bool rc = true;
for(unsigned int i=0; i<kSize; ++i) {
rc = rc && (fArray[i] == rhs[i]);
}
return rc;
}

enum {
/// return no. of matrix rows
kRows = D1,
/// return no. of matrix columns
kCols = D2,
/// return no of elements: rows*columns
kSize = D1*D2
};

private:
//T __attribute__ ((aligned (16))) fArray[kSize];
T  fArray[kSize];
};

//     template<unigned int D>
//     struct Creator {
//       static const RowOffsets<D> & Offsets() {
//          static RowOffsets<D> off;
//           return off;
//       }

/**
Static structure to keep the conversion from (i,j) to offsets in the storage data for a
symmetric matrix
*/

template<unsigned int D>
struct RowOffsets {
inline RowOffsets() {
int v[D];
v[0]=0;
for (unsigned int i=1; i<D; ++i)
v[i]=v[i-1]+i;
for (unsigned int i=0; i<D; ++i) {
for (unsigned int j=0; j<=i; ++j)
fOff[i*D+j] = v[i]+j;
for (unsigned int j=i+1; j<D; ++j)
fOff[i*D+j] = v[j]+i ;
}
}
inline int operator()(unsigned int i, unsigned int j) const { return fOff[i*D+j]; }
inline int apply(unsigned int i) const { return fOff[i]; }
int fOff[D*D];
};

namespace rowOffsetsUtils {

///////////
// Some meta template stuff
template<int...> struct indices{};

template<int I, class IndexTuple, int N>
struct make_indices_impl;

template<int I, int... Indices, int N>
struct make_indices_impl<I, indices<Indices...>, N>
{
typedef typename make_indices_impl<I + 1, indices<Indices..., I>,
N>::type type;
};

template<int N, int... Indices>
struct make_indices_impl<N, indices<Indices...>, N> {
typedef indices<Indices...> type;
};

template<int N>
struct make_indices : make_indices_impl<0, indices<>, N> {};
// end of stuff

template<int I0, class F, int... I>
constexpr std::array<decltype(std::declval<F>()(std::declval<int>())), sizeof...(I)>
do_make(F f, indices<I...>)
{
return  std::array<decltype(std::declval<F>()(std::declval<int>())),
sizeof...(I)>{{ f(I0 + I)... }};
}

template<int N, int I0 = 0, class F>
constexpr std::array<decltype(std::declval<F>()(std::declval<int>())), N>
make(F f) {
return do_make<I0>(f, typename make_indices<N>::type());
}

} // namespace rowOffsetsUtils

//_________________________________________________________________________________
/**
MatRepSym
Matrix storage representation for a symmetric matrix of dimension NxN
This class is a template on the contained type and on the symmetric matrix size, N.
It has as data member an array of type T of size N*(N+1)/2,
containing the lower diagonal block of the matrix.
The order follows the lower diagonal block, still in a row-major convention.
For example for a symmetric 3x3 matrix the order of the 6 elements
\f$\left[a_0,a_1.....a_5 \right]\f$ is:
\f[
M = \left( \begin{array}{ccc}
a_0 & a_1  & a_3  \\
a_1 & a_2  & a_4  \\
a_3 & a_4 & a_5   \end{array} \right)
\f]

@ingroup MatRep
*/
template <class T, unsigned int D>
class MatRepSym {

public:

/* constexpr */ inline MatRepSym(){}

typedef T  value_type;

inline T & operator()(unsigned int i, unsigned int j)
{ return fArray[offset(i, j)]; }

inline /* constexpr */ T const & operator()(unsigned int i, unsigned int j) const
{ return fArray[offset(i, j)]; }

inline T& operator[](unsigned int i) {
return fArray[off(i)];
}

inline /* constexpr */ T const & operator[](unsigned int i) const {
return fArray[off(i)];
}

inline /* constexpr */ T apply(unsigned int i) const {
return fArray[off(i)];
}

inline T* Array() { return fArray; }

inline const T* Array() const { return fArray; }

/**
assignment : only symmetric to symmetric allowed
*/
template <class R>
inline MatRepSym<T, D>& operator=(const R&) {
STATIC_CHECK(0==1,
Cannot_assign_general_to_symmetric_matrix_representation);
return *this;
}
inline MatRepSym<T, D>& operator=(const MatRepSym& rhs) {
for(unsigned int i=0; i<kSize; ++i) fArray[i] = rhs.Array()[i];
return *this;
}

/**
self addition : only symmetric to symmetric allowed
*/
template <class R>
inline MatRepSym<T, D>& operator+=(const R&) {
STATIC_CHECK(0==1,
return *this;
}
inline MatRepSym<T, D>& operator+=(const MatRepSym& rhs) {
for(unsigned int i=0; i<kSize; ++i) fArray[i] += rhs.Array()[i];
return *this;
}

/**
self subtraction : only symmetric to symmetric allowed
*/
template <class R>
inline MatRepSym<T, D>& operator-=(const R&) {
STATIC_CHECK(0==1,
Cannot_substract_general_to_symmetric_matrix_representation);
return *this;
}
inline MatRepSym<T, D>& operator-=(const MatRepSym& rhs) {
for(unsigned int i=0; i<kSize; ++i) fArray[i] -= rhs.Array()[i];
return *this;
}
template <class R>
inline bool operator==(const R& rhs) const {
bool rc = true;
for(unsigned int i=0; i<D*D; ++i) {
rc = rc && (operator[](i) == rhs[i]);
}
return rc;
}

enum {
/// return no. of matrix rows
kRows = D,
/// return no. of matrix columns
kCols = D,
/// return no of elements: rows*columns
kSize = D*(D+1)/2
};

static constexpr int off0(int i) { return i==0 ? 0 : off0(i-1)+i;}
static constexpr int off2(int i, int j) { return j<i ? off0(i)+j : off0(j)+i; }
static constexpr int off1(int i) { return off2(i/D, i%D);}

static int off(int i) {
static constexpr auto v = rowOffsetsUtils::make<D*D>(off1);
return v[i];
}

static inline constexpr unsigned int
offset(unsigned int i, unsigned int j)
{
//if (j > i) std::swap(i, j);
return off(i*D+j);
// return (i>j) ? (i * (i+1) / 2) + j :  (j * (j+1) / 2) + i;
}

private:
//T __attribute__ ((aligned (16))) fArray[kSize];
T fArray[kSize];
};

} // namespace Math
} // namespace ROOT

#endif // MATH_MATRIXREPRESENTATIONSSTATIC_H

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