17faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// This file is part of Eigen, a lightweight C++ template library 27faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// for linear algebra. 37faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// 47faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// This code initially comes from MINPACK whose original authors are: 57faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// Copyright Jorge More - Argonne National Laboratory 67faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// Copyright Burt Garbow - Argonne National Laboratory 77faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// Copyright Ken Hillstrom - Argonne National Laboratory 87faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// 97faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// This Source Code Form is subject to the terms of the Minpack license 107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// (a BSD-like license) described in the campaigned CopyrightMINPACK.txt file. 117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#ifndef EIGEN_LMCOVAR_H 137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#define EIGEN_LMCOVAR_H 147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeznamespace Eigen { 167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeznamespace internal { 187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate <typename Scalar> 207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandezvoid covar( 217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Matrix< Scalar, Dynamic, Dynamic > &r, 227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez const VectorXi& ipvt, 237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Scalar tol = std::sqrt(NumTraits<Scalar>::epsilon()) ) 247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{ 257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez using std::abs; 267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez /* Local variables */ 277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index i, j, k, l, ii, jj; 287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez bool sing; 297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Scalar temp; 307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez /* Function Body */ 327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez const Index n = r.cols(); 337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez const Scalar tolr = tol * abs(r(0,0)); 347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Matrix< Scalar, Dynamic, 1 > wa(n); 357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez eigen_assert(ipvt.size()==n); 367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez /* form the inverse of r in the full upper triangle of r. */ 387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez l = -1; 397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for (k = 0; k < n; ++k) 407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (abs(r(k,k)) > tolr) { 417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez r(k,k) = 1. / r(k,k); 427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for (j = 0; j <= k-1; ++j) { 437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez temp = r(k,k) * r(j,k); 447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez r(j,k) = 0.; 457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez r.col(k).head(j+1) -= r.col(j).head(j+1) * temp; 467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez l = k; 487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez /* form the full upper triangle of the inverse of (r transpose)*r */ 517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez /* in the full upper triangle of r. */ 527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for (k = 0; k <= l; ++k) { 537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for (j = 0; j <= k-1; ++j) 547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez r.col(j).head(j+1) += r.col(k).head(j+1) * r(j,k); 557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez r.col(k).head(k+1) *= r(k,k); 567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez /* form the full lower triangle of the covariance matrix */ 597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez /* in the strict lower triangle of r and in wa. */ 607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for (j = 0; j < n; ++j) { 617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez jj = ipvt[j]; 627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez sing = j > l; 637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for (i = 0; i <= j; ++i) { 647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (sing) 657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez r(i,j) = 0.; 667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez ii = ipvt[i]; 677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (ii > jj) 687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez r(ii,jj) = r(i,j); 697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (ii < jj) 707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez r(jj,ii) = r(i,j); 717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez wa[jj] = r(j,j); 737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez /* symmetrize the covariance matrix in r. */ 767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez r.topLeftCorner(n,n).template triangularView<StrictlyUpper>() = r.topLeftCorner(n,n).transpose(); 777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez r.diagonal() = wa; 787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez} 797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez} // end namespace internal 817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez} // end namespace Eigen 837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez#endif // EIGEN_LMCOVAR_H 85