This file is indexed.

/usr/include/shark/LinAlg/Cholesky.h is in libshark-dev 3.0.1+ds1-2ubuntu1.

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
/*!
 * 
 *
 * \brief       Cholesky Decompositions for a Matrix A = LL^T
 * 
 * 
 * 
 *
 * \author      O. Krause
 * \date        2012
 *
 *
 * \par Copyright 1995-2015 Shark Development Team
 * 
 * <BR><HR>
 * This file is part of Shark.
 * <http://image.diku.dk/shark/>
 * 
 * Shark is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published 
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Shark 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 Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with Shark.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#ifndef SHARK_LINALG_CHOLESKY_H
#define SHARK_LINALG_CHOLESKY_H

#include <shark/LinAlg/Base.h>
#include <shark/LinAlg/BLAS/kernels/potrf.hpp>

namespace shark{ namespace blas{

/**
 * \ingroup shark_globals
 * 
 * @{
 */

/*!
 *  \brief Lower triangular Cholesky decomposition.
 *
 *  Given an \f$ m \times m \f$ symmetric positive definite matrix
 *  \f$A\f$, compute the lower triangular matrix \f$L\f$ such that
 *  \f$A = LL^T \f$.
 *  An exception is thrown if the matrix is not positive definite. 
 *  If you suspect the matrix to be positive semi-definite, use
 *  pivotingCholeskyDecomposition instead
 *
 *  \param  A \f$ m \times m \f$ matrix, which must be symmetric and positive definite
 *  \param	L \f$ m \times m \f$ matrix, which stores the Cholesky factor
 *  \return none
 *
 *
 */
template<class MatrixT,class MatrixL>
void choleskyDecomposition(
	matrix_expression<MatrixT> const& A, 
	matrix_expression<MatrixL>& L
){
	SIZE_CHECK(A().size1() == A().size2());
	size_t m = A().size1();
	ensure_size(L,m, m);
	L().clear();
	for(std::size_t i = 0; i != m; ++i){
		for(std::size_t j = 0; j <= i; ++j){
			L()(i,j) = A()(i,j);
		}
	}
	if(kernels::potrf<lower>(L()) != 0){
		throw SHARKEXCEPTION("[Cholesky Decomposition] The Matrix is not positive definite");
	}
}


/// \brief Updates a covariance factor by a rank one update
///
/// Let \f$ A=LL^T \f$ be a matrix with its lower cholesky factor. Assume we want to update 
/// A using a simple rank-one update \f$ A = \alpha A+ \beta vv^T \f$. This invalidates L and
/// it needs to be recomputed which is O(n^3). instead we can update the factorisation
/// directly by performing a similar, albeit more complex algorithm on L, which can be done
/// in O(L^2). 
/// 
/// Alpha is not required to be positive, but if it is not negative, one has to be carefull
/// that the update would keep A positive definite. Otherwise the decomposition does not
/// exist anymore and an exception is thrown.
///
/// \param L the lower cholesky factor to be updated
/// \param v the update vector
/// \param alpha the scaling factor, must be positive.
/// \param beta the update factor. it Can be positive or negative
template<class Matrix,class Vector>
void choleskyUpdate(
	matrix_expression<Matrix>& L, 
	vector_expression<Vector> const& v, 
	double alpha, double beta
){
	//implementation blatantly stolen from Eigen
	std::size_t n = v().size();
	blas::vector<double> temp = v();
	double betaPrime = 1;
	double a = std::sqrt(alpha);
	for(std::size_t j=0; j != n; ++j)
	{
		double Ljj = a*L()(j,j);
		double dj = Ljj*Ljj;
		double wj = temp(j);
		double swj2 = beta*wj*wj;
		double gamma = dj*betaPrime + swj2;

		double x = dj + swj2/betaPrime;
		if (x <= 0.0)
			throw SHARKEXCEPTION("[choleskyUpdate] update makes matrix indefinite, no update available");
		double nLjj = std::sqrt(x);
		L()(j,j) = nLjj;
		betaPrime += swj2/dj;
		
		// Update the terms of L
		if(j+1 <n)
		{
			subrange(column(L,j),j+1,n) *= a;
			noalias(subrange(temp,j+1,n)) -= (wj/Ljj) * subrange(column(L,j),j+1,n);
			if(gamma == 0)
				continue;
			subrange(column(L,j),j+1,n) *= nLjj/Ljj;
			noalias(subrange(column(L,j),j+1,n))+= (nLjj * beta*wj/gamma)*subrange(temp,j+1,n);
		}
	}
}

/*!
 *  \brief Lower triangular Cholesky decomposition with full pivoting performed in place.
 *
 *  Given an \f$ m \times m \f$ symmetric positive semi-definite matrix
 *  \f$A\f$, compute the lower triangular matrix \f$L\f$ and permutation Matrix P such that
 *  \f$P^TAP = LL^T \f$. If matrix A has rank(A) = k, the first k columns of A hold the full
 *  decomposition, while the rest of the matrix is zero. 
 *  This method is slower than the cholesky decomposition without pivoting but numerically more
 *  stable. The diagonal elements are ordered such that i > j => L(i,i) >= L(j,j)
 *
 *  The implementation used here is described in the working paper 
 *  "LAPACK-Style Codes for Level 2 and 3 Pivoted Cholesky Factorizations"
 *  http://www.netlib.org/lapack/lawnspdf/lawn161.pdf
 *
 * The computation is carried out in place this means A is destroied and replaced by L.
 *  
 *
 *  \param  Lref \f$ m \times m \f$ matrix, which must be symmetric and positive definite. It is replaced by L in the end.
 *  \param  P The pivoting matrix
 *  \return The rank of the matrix A
 */
template<class MatrixL>
std::size_t pivotingCholeskyDecompositionInPlace(
	shark::blas::matrix_expression<MatrixL>& Lref,
	PermutationMatrix& P
);

/*!
 *  \brief Lower triangular Cholesky decomposition with full pivoting
 *
 *  Given an \f$ m \times m \f$ symmetric positive semi-definite matrix
 *  \f$A\f$, compute the lower triangular matrix \f$L\f$ and permutation Matrix P such that
 *  \f$P^TAP = LL^T \f$. If matrix A has rank(A) = k, the first k columns of A hold the full
 *  decomposition, while the rest of the matrix is zero. 
 *  This method is slower than the cholesky decomposition without pivoting but numerically more
 *  stable. The diagonal elements are ordered such that i > j => L(i,i) >= L(j,j)
 *
 *  The implementation used here is described in the working paper 
 *  "LAPACK-Style Codes for Level 2 and 3 Pivoted Cholesky Factorizations"
 *  http://www.netlib.org/lapack/lawnspdf/lawn161.pdf
 *  
 *
 *  \param  A \f$ m \times m \f$ matrix, which must be symmetric and positive definite
 *  \param  P The pivoting matrix
 *  \param  L \f$ m \times m \f$ matrix, which stores the Cholesky factor
 *  \return The rank of the matrix A
 *
 *
 */
template<class MatrixA,class MatrixL>
std::size_t pivotingCholeskyDecomposition(
	matrix_expression<MatrixA> const& A,
	PermutationMatrix& P,
	matrix_expression<MatrixL>& L
){	
	//ensure sizes are correct
	SIZE_CHECK(A().size1() == A().size2());
	size_t m = A().size1();
	ensure_size(L,m,m);
	noalias(L()) = A;
	return pivotingCholeskyDecompositionInPlace(L,P);
}

/** @}*/
}}

//implementation of the template functions
#include "Impl/Cholesky.inl"

#endif