This file is indexed.

/usr/include/Rivet/Math/eigen/ludecompositionbase.h is in librivet-dev 1.8.3-1.1.

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
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2006-2007 Benoit Jacob <jacob@math.jussieu.fr>
//
// Eigen is free software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along
// with Eigen; if not, write to the Free Software Foundation, Inc., 51
// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. This exception does not invalidate any other reasons why a work
// based on this file might be covered by the GNU General Public License.

/** \file ludecompositionbase.h
  * \brief Internal file
  */

#ifndef EIGEN_LUDECOMPOSITIONBASE_H
#define EIGEN_LUDECOMPOSITIONBASE_H

#include "util.h"

namespace Eigen
{

/** \ingroup internalbases
  *
  * \ingroup ludecomp
  *
  * \brief internal base class
  *
  * This class template is only internally used in Eigen.
  */
template<typename T,
         typename MatrixType,
         typename VectorType,
         typename IntVecType>
class LUDecompositionBase
{

public:

    ~LUDecompositionBase() {}

    /**
      * This method returns the determinant of the square matrix A of which
      * *this is the LU decomposition. It has only linear complexity
      * (that is, O(n) where n is the dimension of the square matrix)
      * as the LU decomposition has already been computed.
      *
      * Warning: a determinant can be very big or small, so for matrices
      * of large dimension (like a 50-by-50 matrix) there can be a risk of
      * overflow/underflow.
      */
    T determinant() const;

    /**
      * Returns the dimension (size) of square matrix A
      * of which *this is the LU decomposition -- just in case you forgot it!
      */
    int dim() const
    { return m_dim; }

    /**
      * Returns the dimension of the kernel of the square matrix A
      * of which *this is the LU decomposition. It is very fast because the
      * computation has already been done during the LU decomposition.
      */
    int dimKer() const
    { return m_dimKer; }

    /**
      * Returns the rank of the square matrix A of which *this is
      * the LU decomposition. It is very fast because the
      * computation has already been done during the LU decomposition.
      */
    int rank() const
    { return( m_dim - m_dimKer ); }

    /**
      * Returns true if the square matrix A, of which *this is
      * the LU decomposition, is invertible. It returns false if it is singular.
      * It is very fast because the computation has already been done during
      * the LU decomposition.
      */
    bool isInvertible() const
    { return( m_dimKer == 0 ); }

    /**
      * This method computes a basis of the kernel of the matrix A of which
      * *this is the LU decomposition.
      *
      * The \a result argument is a pointer to the matrix in which the result
      * will be stored. After calling this method, the \a dimKer() first
      * columns of \a result form a basis of the kernel of A. If A
      * is invertible, then dimKer()==0 and this method does nothing.
      *
      * @returns true is the matrix is non-invertible, hence has a nonzero
      * kernel; false if the matrix is invertible.
      */
    bool computeBasisKer( MatrixType * result) const;

    /**
      * Computes an antecedent of \a v by the matrix \a A of which *this is a
      * LU decomposition. In other words, this method computes a vector \a u
      * such that \a A \a u = \a v.
      * If such an antecedent \a u doesn't exist, this method does nothing.
      *
      * @returns true if an antecedent exists, false if no antecedent exists.
      *
      * Notes:
      *
      * 1. The returned vector u is only one solution of the equation Au=v,
      * which can have more than one solution if A is non-invertible. To get
      * a basis of the whole (affine) space of solutions, use computeBasisKer().
      *
      * \sa computeBasisKer()
      */
    bool computeSomeAntecedent
    ( const VectorType & v, VectorType * result ) const;

    /**
      * Computes the inverse matrix of A, where A
      * is the matrix of which *this is the LU decomposition, and
      * stores it in *result.
      *
      * If A is non-invertible, this method does nothing.
      *
      * \returns true if A is invertible, false otherwise.
      *
      */
    bool computeInverse( MatrixType * result ) const;

    /**
      * This methods returns the inverse matrix of A, where A
      * is the matrix of which *this is the LU decomposition. If A is
      * non-invertible, the returned value is undefined.
      *
      * This method calls computeInverse(), so the same remarks as for
      * computeInverse() apply here.
      *
      * \return_by_value
      *
      * \sa computeInverse()
      */
    MatrixType inverse() const
    {
        MatrixType m( m_LU.size() );
        computeInverse( &m );
        return m;
    }

    /**
      * Returns the member m_LU, which stores the matrices L and U.
      * See member m_LU and the class's comment.
      */
    MatrixType & LU() { return m_LU; }
    const MatrixType & LU() const { return m_LU; }

    /**
      * Returns the member m_P, which stores the permutation P.
      * See member m_P and the class's comment.
      */
    IntVecType & P() { return m_P; }
    const IntVecType & P() const { return m_P; }


    /**
      * Returns the member m_Q, which stores the permutation Q.
      * See member m_Q and the class's comment.
      */
    IntVecType & Q() { return m_Q; }
    const IntVecType & Q() const { return m_Q; }

protected:

    /**
      * The helper method actually computing the LU decomposition.
      * Called by the constructor.
      *
      * For internal reasons it is public, but you should never call it.
      */
    void perform ( const MatrixType & A );

    /**
      * The dimension of the matrix A of which *this is the LU decomposition
      */
    int m_dim;

    /**
      * The permutation matrices P and Q are stored in these permutations p, q.
      * They are understood as follows: the permutation p maps k to p[k].
      * Same for q. So, in terms of matrices, P moves the k-th row to the
      * p[k]-th row, and Q moves the k-th column to the q[k]-th column.
      */
    IntVecType m_P, m_Q;

    /**
      * This is equal to the determinant of the product matrix PQ, or
      * equivalently, to the signature of the permutation pq.
      * This is used by the determinant() method.
      */
    int m_detPQ;

    /**
      * This matrix holds the data of the L and U matrices of the LU
      * decomposition, as follows. The part above the diagonal (including
      * the diagonal) is U. The part strictly below the diagonal is L.
      * As U is upper triangular, L is lower triangular, and L has its diagonal
      * entries all equal to 1, this holds all the data of the matrices L and U.
      * Also note that the Eigenvalues of U are stored in decreasing order of
      * absolute value.
      */
    MatrixType m_LU;

    /**
      * The dimension of the kernel of the square matrix A
      * of which *this is the LU decomposition.
      */
    int m_dimKer;

    /**
      * The Eigenvalue of U that has biggest absolute value.
      */
    T m_biggestEigenValueU;

};

template<typename T,
         typename MatrixType,
         typename VectorType,
         typename IntVecType>
void LUDecompositionBase<T, MatrixType, VectorType, IntVecType>::perform
( const MatrixType & A )
{
    m_dim = A.size();

    m_P.resize( m_dim );
    m_Q.resize( m_dim );


    //initially set m_LU to be a copy of A
    m_LU = A;

    // initially set P and Q to be the identity permutation
    for( int k = 0; k < dim(); k++ )
    {
        P()[k] = k;
        Q()[k] = k;
    }

    // if dim() == 1, then we're already almost done!
    if( dim() == 1 )
    {
        m_detPQ = 1;
        m_biggestEigenValueU = LU().array()[0];
        m_dimKer = ( std::abs(m_biggestEigenValueU) == static_cast<T>(0) );
            // there's nothing to compare m_biggestEigenValueU to, so we have
            // to content ourselves with that test. abs() is here because
            // in some implementations, std::complex has no operator==.
        return;
    }

    // temporary arrays used to store the lists of transpositions whose products
    // will be P and Q respectively
    IntVecType transpositionsP( dim() );
    IntVecType transpositionsQ( dim() );

    // the number of transpositions stored in transpositionsP
    // and transpositionsQ. This will be used to compute m_detPQ.
    int number_of_transpos = 0;

    // Let's now perform the LU decomposition with complete pivoting
    // following Algorithm 3.4.2 in the book Matrix Computations (3rd ed.)
    // by Golub & van Loan
    for( int k = 0; k <= dim() - 2; k++)
    {
        // Determine row_max_abs and col_max_abs greater or equal to k
        // maximizing abs(LU()(row_max_abs, col_max_abs))
        int row_max_abs, col_max_abs, row, col;

        LU().findBiggestEntry( &row_max_abs, &col_max_abs, k );

        T biggestEntry = LU()( row_max_abs, col_max_abs );

        // swap the k-th and the row_max_abs-th rows
        T *row_k_ptr = LU().array() + k;
        T *row_max_abs_ptr = LU().array() + row_max_abs;
        for( col = 0; col < dim(); col++ )
        {
            T tmp = *row_k_ptr;
            *row_k_ptr = *row_max_abs_ptr;
            *row_max_abs_ptr = tmp;
            row_k_ptr += dim();
            row_max_abs_ptr += dim();
        }

        // swap the k-th and the col_max_abs-th columns
        T *col_k_ptr = LU().array() + k * dim();
        T *col_max_abs_ptr = LU().array() + col_max_abs * dim();
        for( row = 0; row < dim(); row++ )
        {
            T tmp = *col_k_ptr;
            *col_k_ptr = *col_max_abs_ptr;
            *col_max_abs_ptr = tmp;
            col_k_ptr++;
            col_max_abs_ptr++;
        }

        // store the transpositions
        transpositionsP[k] = row_max_abs;
        transpositionsQ[k] = col_max_abs;
        number_of_transpos += ( k != row_max_abs ) + ( k != col_max_abs );

        // test if the diagonal entry LU()(k, k) is nonzero
        T lu_k_k = LU()(k, k);
        if( ! Util::isNegligible( lu_k_k, biggestEntry ) )
        {
            // divide entries (k+1...n) in column k by lu_k_k
            T *entry_ptr = &(LU()( k + 1, k ));
            for( row = k + 1; row < dim(); row++ )
            {
                *entry_ptr /= lu_k_k;
                entry_ptr++;
            }

            // for row and col greater or equal to k+1, perform
            // LU()(row,col) -= LU()(row,k) * LU()(k,col)
            entry_ptr = &(LU()( k + 1, k + 1 ));
            row_k_ptr = &(LU()( k, k + 1));
            col_k_ptr = &(LU()( k + 1, k ));
            for( col = k + 1; col < dim(); col++ )
            {
                for( row = k + 1; row < dim(); row++ )
                {
                    *entry_ptr -= (*row_k_ptr) * (*col_k_ptr);
                    col_k_ptr++;
                    entry_ptr++;
                }
                col_k_ptr -= dim() - k - 1;
                row_k_ptr += dim();
                entry_ptr += k + 1;
            }
        }
    }
    // end of algorithm 3.4.2 in the book by Golub & van Loan.
    // it now remains to compute the permutations P, Q, the determinant
    // m_detPQ, the biggest Eigenvalue m_biggestEigenValueU of U,
    // and the dimension m_dimKer of the kernel of A.

    // let's first compute P and Q. They are the products of the transpositions
    // in transpositionsP and transpositionsQ, but not in the same order
    // (and order does matter here).

    for( int k = 0; k <= dim() - 2; k++)
    {
        int tmp;
        tmp = Q()[k];
        Q()[k] = Q()[ transpositionsQ[k] ];
        Q()[ transpositionsQ[k] ] = tmp;

        int i = dim() - 2 - k;
        tmp = P()[i];
        P()[i] = P()[ transpositionsP[i] ];
        P()[ transpositionsP[i] ] = tmp;
    }

    // let's now compute m_detPQ
    if( number_of_transpos % 2 ) // if number_of_transpos is odd
        m_detPQ = -1;
    else
        m_detPQ = 1;

    // let's now compute m_biggestEigenValueU
    // the diagonal entries in LU() are the Eigenvalues of U
    m_biggestEigenValueU = static_cast<T>(0);
    for( int k = 0; k <= dim() - 1; k++)
        if( std::abs( LU()( k, k ) ) > std::abs( m_biggestEigenValueU ) )
            m_biggestEigenValueU = LU()( k, k );

    // at last, let's compute the dimension m_dimKer of the kernel of A
    // it suffices to count how many Eigenvalues of U are zero
    // (as P, L and Q are invertible).
    m_dimKer = 0;
    for( int k = 0; k <= dim() - 1; k++)
        m_dimKer += Util::isNegligible( LU()( k, k ), m_biggestEigenValueU );
}

template<typename T,
         typename MatrixType,
         typename VectorType,
         typename IntVecType>
T LUDecompositionBase<T, MatrixType, VectorType, IntVecType>::determinant() const
{
    if( ! isInvertible() ) return static_cast<T>(0);
    T ret = m_detPQ;
    for (int i = 0; i < dim() * dim(); i += (dim()+1) )
        ret *= LU().array()[i];
    return ret;
}

template<typename T,
         typename MatrixType,
         typename VectorType,
         typename IntVecType>
bool LUDecompositionBase<T, MatrixType, VectorType, IntVecType>::computeBasisKer
( MatrixType * result) const
{
    if( isInvertible() ) return false;
    result->resize( dim() );

    /* Let us use the following lemma:
     *
     * Lemma: If the matrix A has the LU decomposition PAQ = LU,
     * then Ker A = Q( Ker U ).
     *
     * Proof: trivial: just keep in mind that P, Q, L are invertible.
     */

    /* Thus, all we need to do is to compute Ker U, and then apply Q.
     *
     * U is upper triangular, with Eigenvalues sorted in decreasing order of
     * absolute value. Thus, the diagonal of U ends with exactly
     * m_dimKer zero's. Let us use that to construct m_dimKer linearly
     * independent vectors in Ker U.
     */

    VectorType tmpvector(dim());

    for( int k = 0; k < m_dimKer; k++ )
    {
        // let tmpvector end with 0,...,0,1,0,...,0 where the 1 occurs at
        // position k counting from the last one.
        for( int i = 0; i < m_dimKer; i++ )
        {
            tmpvector[ dim() - 1 - i ] = static_cast<T>( i == k );
        }

        /* now comes the part that's difficult to explain in a comment...
         * We've just set the m_dimKer last coords of tmpvector.
         * Now we want to compute the (dim()-m_dimKer) first coords.
         * As U has rank dim()-m_dimKer, these are uniquely determined.
         * We just have to solve the equation VX=Y where V is the square
         * matrix formed of the (dim()-m_dimKer) first rows and columns
         * of U, X is what we're looking for, and Y is minus the
         * (dim() - 1 - k)-th column of U.
         */

        const T *colptr = LU().array() + (dim() - 1 - k) * dim();
        int maxrow = dim() - m_dimKer - 1;
        for( int i = maxrow; i >= 0; i-- ) // i must be signed!
        {
            T *tmpvecptr = &(tmpvector[i]);
            *tmpvecptr = - colptr[i];
            const T *rowptr = &( LU()( i, i ) );
            const T *denomptr = rowptr;
            for( int j = i + 1; j <= maxrow; j++ )
            {
                rowptr += dim();
                *tmpvecptr -= tmpvector[j] * (*rowptr);
            }
            *tmpvecptr /= *denomptr;
        }

        //now tmpvector is really a vector in Ker U, so it only remains to
        //apply Q to it and store the result as the k-th column of *ret.
        for( int i = 0; i < dim(); i++)
            (*result)(Q()[i], k) = tmpvector[i];
    }
    return true;
}

template<typename T,
         typename MatrixType,
         typename VectorType,
         typename IntVecType>
bool LUDecompositionBase<T, MatrixType, VectorType, IntVecType>::computeSomeAntecedent
( const VectorType & v, VectorType * result ) const
{
    /* The decomposition PAQ = LU can be rewritten as A = P^{-1} L U Q^{-1}.
     * So we proceed as follows:
     * Step 1: compute b = Pv.
     * Step 2: compute a such that La = b. Exists because L is invertible.
     * Step 3: compute b such that Ub = a. Check if such b really exists.
     * Step 4: return Qb;
     */

    VectorType a(dim());
    VectorType b(dim());

    // Step 1
    for( int i = 0; i < dim(); i++)
        b[ P()[i] ] = v[i];

    // Step 2
    for( int i = 0; i < dim(); i++)
    {
        a[i] = b[i];
        const T *rowptr = &( LU()( i, 0 ) );
        for( int j = 0; j < i; j++ )
        {
            a[i] -= a[j] * (*rowptr);
            rowptr += dim();
        }
    }

    // Step 3
    for( int i = dim() - 1; i >= 0; i--) // i must be signed!
    {
        const T *rowptr = &( LU()( i, i ) );
        const T *denomptr = rowptr;

        // if the current Eigenvalue of U is zero
        if( Util::isNegligible( *denomptr, m_biggestEigenValueU ) )
        {
            // if the current vector coord is also zero
            if( Util::isNegligible( a[i], m_biggestEigenValueU ) )
            {   // we can choose whatever value for b[i], so let's take
                // a nonzero value, so that b will be a nonzero vector
                b[i] = static_cast<T>(1);
            }
            else
            {
                // the equation has no solution (try solving 0*x = 1)
                return false;
            }
        }
        else // the current Eigenvalue of U is nonzero
        {
            b[i] = a[i];
            for( int j = i + 1; j <= dim() - 1; j++ )
            {
                rowptr += dim();
                b[i] -= b[j] * (*rowptr);
            }
            b[i] /= *denomptr;
        }
    }

    // Step 4
    for( int i = 0; i < dim(); i++)
        (*result)[ Q()[i] ] = b[i];
    return true;
}

template<typename T,
         typename MatrixType,
         typename VectorType,
         typename IntVecType>
bool LUDecompositionBase<T, MatrixType, VectorType, IntVecType>
    ::computeInverse( MatrixType * result ) const
{
    result->resize( dim() );
    if( ! isInvertible() ) return false;

    VectorType basis_vector(dim());
    VectorType antecedent(dim());
    for( int i = 0; i < dim(); i++ ) basis_vector(i) = static_cast<T>(0);

    for( int col = 0; col < dim(); col++ )
    {
        basis_vector(col) = static_cast<T>(1);
        computeSomeAntecedent( basis_vector, &antecedent );
        result->setColumn( col, antecedent );
        basis_vector(col) = static_cast<T>(0);
    }
    return true;
}

} // namespace Eigen

#endif // EIGEN_LUDECOMPOSITIONBASE_H