1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra.
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2010-2011 Gael Guennebaud <gael.guennebaud@inria.fr>
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "common.h"
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include <Eigen/LU>
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// computes an LU factorization of a general M-by-N matrix A using partial pivoting with row interchanges
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathEIGEN_LAPACK_FUNC(getrf,(int *m, int *n, RealScalar *pa, int *lda, int *ipiv, int *info))
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *info = 0;
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        if(*m<0)                  *info = -1;
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else  if(*n<0)                  *info = -2;
19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else  if(*lda<std::max(1,*m))   *info = -4;
20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(*info!=0)
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int e = -*info;
23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return xerbla_(SCALAR_SUFFIX_UP"GETRF", &e, 6);
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(*m==0 || *n==0)
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return 0;
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* a = reinterpret_cast<Scalar*>(pa);
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int nb_transpositions;
317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  int ret = int(Eigen::internal::partial_lu_impl<Scalar,ColMajor,int>
327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                     ::blocked_lu(*m, *n, a, *lda, ipiv, nb_transpositions));
33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for(int i=0; i<std::min(*m,*n); ++i)
35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ipiv[i]++;
36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(ret>=0)
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    *info = ret+1;
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return 0;
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//GETRS solves a system of linear equations
44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//    A * X = B  or  A' * X = B
45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//  with a general N-by-N matrix A using the LU factorization computed  by GETRF
46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathEIGEN_LAPACK_FUNC(getrs,(char *trans, int *n, int *nrhs, RealScalar *pa, int *lda, int *ipiv, RealScalar *pb, int *ldb, int *info))
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *info = 0;
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        if(OP(*trans)==INVALID)  *info = -1;
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else  if(*n<0)                 *info = -2;
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else  if(*nrhs<0)              *info = -3;
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else  if(*lda<std::max(1,*n))  *info = -5;
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else  if(*ldb<std::max(1,*n))  *info = -8;
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(*info!=0)
55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    int e = -*info;
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return xerbla_(SCALAR_SUFFIX_UP"GETRS", &e, 6);
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* a = reinterpret_cast<Scalar*>(pa);
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* b = reinterpret_cast<Scalar*>(pb);
62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  MatrixType lu(a,*n,*n,*lda);
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  MatrixType B(b,*n,*nrhs,*ldb);
64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for(int i=0; i<*n; ++i)
66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ipiv[i]--;
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(OP(*trans)==NOTR)
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    B = PivotsType(ipiv,*n) * B;
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    lu.triangularView<UnitLower>().solveInPlace(B);
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    lu.triangularView<Upper>().solveInPlace(B);
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(OP(*trans)==TR)
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    lu.triangularView<Upper>().transpose().solveInPlace(B);
76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    lu.triangularView<UnitLower>().transpose().solveInPlace(B);
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    B = PivotsType(ipiv,*n).transpose() * B;
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(OP(*trans)==ADJ)
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    lu.triangularView<Upper>().adjoint().solveInPlace(B);
82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    lu.triangularView<UnitLower>().adjoint().solveInPlace(B);
83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    B = PivotsType(ipiv,*n).transpose() * B;
84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  for(int i=0; i<*n; ++i)
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ipiv[i]++;
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return 0;
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
90