1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra.
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2009-2010 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
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathint EIGEN_BLAS_FUNC(gemm)(char *opa, char *opb, int *m, int *n, int *k, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pb, int *ldb, RealScalar *pbeta, RealScalar *pc, int *ldc)
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//   std::cerr << "in gemm " << *opa << " " << *opb << " " << *m << " " << *n << " " << *k << " " << *lda << " " << *ldb << " " << *ldc << " " << *palpha << " " << *pbeta << "\n";
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef void (*functype)(DenseIndex, DenseIndex, DenseIndex, const Scalar *, DenseIndex, const Scalar *, DenseIndex, Scalar *, DenseIndex, Scalar, internal::level3_blocking<Scalar,Scalar>&, Eigen::internal::GemmParallelInfo<DenseIndex>*);
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static functype func[12];
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static bool init = false;
19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(!init)
20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(int k=0; k<12; ++k)
22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      func[k] = 0;
23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (NOTR << 2)] = (internal::general_matrix_matrix_product<DenseIndex,Scalar,ColMajor,false,Scalar,ColMajor,false,ColMajor>::run);
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (NOTR << 2)] = (internal::general_matrix_matrix_product<DenseIndex,Scalar,RowMajor,false,Scalar,ColMajor,false,ColMajor>::run);
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (NOTR << 2)] = (internal::general_matrix_matrix_product<DenseIndex,Scalar,RowMajor,Conj, Scalar,ColMajor,false,ColMajor>::run);
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (TR   << 2)] = (internal::general_matrix_matrix_product<DenseIndex,Scalar,ColMajor,false,Scalar,RowMajor,false,ColMajor>::run);
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (TR   << 2)] = (internal::general_matrix_matrix_product<DenseIndex,Scalar,RowMajor,false,Scalar,RowMajor,false,ColMajor>::run);
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (TR   << 2)] = (internal::general_matrix_matrix_product<DenseIndex,Scalar,RowMajor,Conj, Scalar,RowMajor,false,ColMajor>::run);
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (ADJ  << 2)] = (internal::general_matrix_matrix_product<DenseIndex,Scalar,ColMajor,false,Scalar,RowMajor,Conj, ColMajor>::run);
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (ADJ  << 2)] = (internal::general_matrix_matrix_product<DenseIndex,Scalar,RowMajor,false,Scalar,RowMajor,Conj, ColMajor>::run);
31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (ADJ  << 2)] = (internal::general_matrix_matrix_product<DenseIndex,Scalar,RowMajor,Conj, Scalar,RowMajor,Conj, ColMajor>::run);
32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    init = true;
33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* a = reinterpret_cast<Scalar*>(pa);
36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* b = reinterpret_cast<Scalar*>(pb);
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* c = reinterpret_cast<Scalar*>(pc);
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar alpha  = *reinterpret_cast<Scalar*>(palpha);
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar beta   = *reinterpret_cast<Scalar*>(pbeta);
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int info = 0;
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(OP(*opa)==INVALID)                                               info = 1;
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(OP(*opb)==INVALID)                                          info = 2;
44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*m<0)                                                       info = 3;
45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*n<0)                                                       info = 4;
46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*k<0)                                                       info = 5;
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*lda<std::max(1,(OP(*opa)==NOTR)?*m:*k))                    info = 8;
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*ldb<std::max(1,(OP(*opb)==NOTR)?*k:*n))                    info = 10;
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*ldc<std::max(1,*m))                                        info = 13;
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(info)
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return xerbla_(SCALAR_SUFFIX_UP"GEMM ",&info,6);
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(beta!=Scalar(1))
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(beta==Scalar(0)) matrix(c, *m, *n, *ldc).setZero();
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else                matrix(c, *m, *n, *ldc) *= beta;
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  internal::gemm_blocking_space<ColMajor,Scalar,Scalar,Dynamic,Dynamic,Dynamic> blocking(*m,*n,*k);
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int code = OP(*opa) | (OP(*opb) << 2);
62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  func[code](*m, *n, *k, a, *lda, b, *ldb, c, *ldc, alpha, blocking, 0);
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return 0;
64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathint EIGEN_BLAS_FUNC(trsm)(char *side, char *uplo, char *opa, char *diag, int *m, int *n, RealScalar *palpha,  RealScalar *pa, int *lda, RealScalar *pb, int *ldb)
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//   std::cerr << "in trsm " << *side << " " << *uplo << " " << *opa << " " << *diag << " " << *m << "," << *n << " " << *palpha << " " << *lda << " " << *ldb<< "\n";
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef void (*functype)(DenseIndex, DenseIndex, const Scalar *, DenseIndex, Scalar *, DenseIndex, internal::level3_blocking<Scalar,Scalar>&);
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static functype func[32];
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static bool init = false;
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(!init)
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(int k=0; k<32; ++k)
76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      func[k] = 0;
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (LEFT  << 2) | (UP << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Upper|0,          false,ColMajor,ColMajor>::run);
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (LEFT  << 2) | (UP << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Lower|0,          false,RowMajor,ColMajor>::run);
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (LEFT  << 2) | (UP << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Lower|0,          Conj, RowMajor,ColMajor>::run);
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Upper|0,          false,ColMajor,ColMajor>::run);
83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Lower|0,          false,RowMajor,ColMajor>::run);
84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Lower|0,          Conj, RowMajor,ColMajor>::run);
85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (LEFT  << 2) | (LO << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Lower|0,          false,ColMajor,ColMajor>::run);
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (LEFT  << 2) | (LO << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Upper|0,          false,RowMajor,ColMajor>::run);
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (LEFT  << 2) | (LO << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Upper|0,          Conj, RowMajor,ColMajor>::run);
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Lower|0,          false,ColMajor,ColMajor>::run);
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Upper|0,          false,RowMajor,ColMajor>::run);
92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Upper|0,          Conj, RowMajor,ColMajor>::run);
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (LEFT  << 2) | (UP << 3) | (UNIT  << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Upper|UnitDiag,false,ColMajor,ColMajor>::run);
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (LEFT  << 2) | (UP << 3) | (UNIT  << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Lower|UnitDiag,false,RowMajor,ColMajor>::run);
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (LEFT  << 2) | (UP << 3) | (UNIT  << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Lower|UnitDiag,Conj, RowMajor,ColMajor>::run);
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (RIGHT << 2) | (UP << 3) | (UNIT  << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Upper|UnitDiag,false,ColMajor,ColMajor>::run);
100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (RIGHT << 2) | (UP << 3) | (UNIT  << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Lower|UnitDiag,false,RowMajor,ColMajor>::run);
101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (RIGHT << 2) | (UP << 3) | (UNIT  << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Lower|UnitDiag,Conj, RowMajor,ColMajor>::run);
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (LEFT  << 2) | (LO << 3) | (UNIT  << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Lower|UnitDiag,false,ColMajor,ColMajor>::run);
104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (LEFT  << 2) | (LO << 3) | (UNIT  << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Upper|UnitDiag,false,RowMajor,ColMajor>::run);
105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (LEFT  << 2) | (LO << 3) | (UNIT  << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Upper|UnitDiag,Conj, RowMajor,ColMajor>::run);
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (RIGHT << 2) | (LO << 3) | (UNIT  << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Lower|UnitDiag,false,ColMajor,ColMajor>::run);
108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (RIGHT << 2) | (LO << 3) | (UNIT  << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Upper|UnitDiag,false,RowMajor,ColMajor>::run);
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (RIGHT << 2) | (LO << 3) | (UNIT  << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Upper|UnitDiag,Conj, RowMajor,ColMajor>::run);
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    init = true;
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* a = reinterpret_cast<Scalar*>(pa);
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* b = reinterpret_cast<Scalar*>(pb);
116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar  alpha = *reinterpret_cast<Scalar*>(palpha);
117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int info = 0;
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(SIDE(*side)==INVALID)                                            info = 1;
120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(UPLO(*uplo)==INVALID)                                       info = 2;
121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(OP(*opa)==INVALID)                                          info = 3;
122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(DIAG(*diag)==INVALID)                                       info = 4;
123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*m<0)                                                       info = 5;
124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*n<0)                                                       info = 6;
125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*lda<std::max(1,(SIDE(*side)==LEFT)?*m:*n))                 info = 9;
126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*ldb<std::max(1,*m))                                        info = 11;
127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(info)
128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return xerbla_(SCALAR_SUFFIX_UP"TRSM ",&info,6);
129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int code = OP(*opa) | (SIDE(*side) << 2) | (UPLO(*uplo) << 3) | (DIAG(*diag) << 4);
131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(SIDE(*side)==LEFT)
133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    internal::gemm_blocking_space<ColMajor,Scalar,Scalar,Dynamic,Dynamic,Dynamic,4> blocking(*m,*n,*m);
135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[code](*m, *n, a, *lda, b, *ldb, blocking);
136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else
138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    internal::gemm_blocking_space<ColMajor,Scalar,Scalar,Dynamic,Dynamic,Dynamic,4> blocking(*m,*n,*n);
140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[code](*n, *m, a, *lda, b, *ldb, blocking);
141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(alpha!=Scalar(1))
144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    matrix(b,*m,*n,*ldb) *= alpha;
145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return 0;
147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// b = alpha*op(a)*b  for side = 'L'or'l'
151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// b = alpha*b*op(a)  for side = 'R'or'r'
152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathint EIGEN_BLAS_FUNC(trmm)(char *side, char *uplo, char *opa, char *diag, int *m, int *n, RealScalar *palpha,  RealScalar *pa, int *lda, RealScalar *pb, int *ldb)
153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//   std::cerr << "in trmm " << *side << " " << *uplo << " " << *opa << " " << *diag << " " << *m << " " << *n << " " << *lda << " " << *ldb << " " << *palpha << "\n";
1557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  typedef void (*functype)(DenseIndex, DenseIndex, DenseIndex, const Scalar *, DenseIndex, const Scalar *, DenseIndex, Scalar *, DenseIndex, const Scalar&, internal::level3_blocking<Scalar,Scalar>&);
156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static functype func[32];
157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static bool init = false;
158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(!init)
159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(int k=0; k<32; ++k)
161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      func[k] = 0;
162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (LEFT  << 2) | (UP << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|0,          true, ColMajor,false,ColMajor,false,ColMajor>::run);
164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (LEFT  << 2) | (UP << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|0,          true, RowMajor,false,ColMajor,false,ColMajor>::run);
165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (LEFT  << 2) | (UP << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|0,          true, RowMajor,Conj, ColMajor,false,ColMajor>::run);
166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|0,          false,ColMajor,false,ColMajor,false,ColMajor>::run);
168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|0,          false,ColMajor,false,RowMajor,false,ColMajor>::run);
169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|0,          false,ColMajor,false,RowMajor,Conj, ColMajor>::run);
170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (LEFT  << 2) | (LO << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|0,          true, ColMajor,false,ColMajor,false,ColMajor>::run);
172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (LEFT  << 2) | (LO << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|0,          true, RowMajor,false,ColMajor,false,ColMajor>::run);
173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (LEFT  << 2) | (LO << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|0,          true, RowMajor,Conj, ColMajor,false,ColMajor>::run);
174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|0,          false,ColMajor,false,ColMajor,false,ColMajor>::run);
176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|0,          false,ColMajor,false,RowMajor,false,ColMajor>::run);
177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|0,          false,ColMajor,false,RowMajor,Conj, ColMajor>::run);
178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (LEFT  << 2) | (UP << 3) | (UNIT  << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|UnitDiag,true, ColMajor,false,ColMajor,false,ColMajor>::run);
180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (LEFT  << 2) | (UP << 3) | (UNIT  << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|UnitDiag,true, RowMajor,false,ColMajor,false,ColMajor>::run);
181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (LEFT  << 2) | (UP << 3) | (UNIT  << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|UnitDiag,true, RowMajor,Conj, ColMajor,false,ColMajor>::run);
182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (RIGHT << 2) | (UP << 3) | (UNIT  << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|UnitDiag,false,ColMajor,false,ColMajor,false,ColMajor>::run);
184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (RIGHT << 2) | (UP << 3) | (UNIT  << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|UnitDiag,false,ColMajor,false,RowMajor,false,ColMajor>::run);
185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (RIGHT << 2) | (UP << 3) | (UNIT  << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|UnitDiag,false,ColMajor,false,RowMajor,Conj, ColMajor>::run);
186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (LEFT  << 2) | (LO << 3) | (UNIT  << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|UnitDiag,true, ColMajor,false,ColMajor,false,ColMajor>::run);
188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (LEFT  << 2) | (LO << 3) | (UNIT  << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|UnitDiag,true, RowMajor,false,ColMajor,false,ColMajor>::run);
189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (LEFT  << 2) | (LO << 3) | (UNIT  << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|UnitDiag,true, RowMajor,Conj, ColMajor,false,ColMajor>::run);
190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (RIGHT << 2) | (LO << 3) | (UNIT  << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|UnitDiag,false,ColMajor,false,ColMajor,false,ColMajor>::run);
192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (RIGHT << 2) | (LO << 3) | (UNIT  << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|UnitDiag,false,ColMajor,false,RowMajor,false,ColMajor>::run);
193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (RIGHT << 2) | (LO << 3) | (UNIT  << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|UnitDiag,false,ColMajor,false,RowMajor,Conj, ColMajor>::run);
194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    init = true;
196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* a = reinterpret_cast<Scalar*>(pa);
199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* b = reinterpret_cast<Scalar*>(pb);
200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar  alpha = *reinterpret_cast<Scalar*>(palpha);
201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int info = 0;
203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(SIDE(*side)==INVALID)                                            info = 1;
204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(UPLO(*uplo)==INVALID)                                       info = 2;
205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(OP(*opa)==INVALID)                                          info = 3;
206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(DIAG(*diag)==INVALID)                                       info = 4;
207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*m<0)                                                       info = 5;
208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*n<0)                                                       info = 6;
209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*lda<std::max(1,(SIDE(*side)==LEFT)?*m:*n))                 info = 9;
210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*ldb<std::max(1,*m))                                        info = 11;
211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(info)
212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return xerbla_(SCALAR_SUFFIX_UP"TRMM ",&info,6);
213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int code = OP(*opa) | (SIDE(*side) << 2) | (UPLO(*uplo) << 3) | (DIAG(*diag) << 4);
215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(*m==0 || *n==0)
217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return 1;
218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // FIXME find a way to avoid this copy
220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Matrix<Scalar,Dynamic,Dynamic,ColMajor> tmp = matrix(b,*m,*n,*ldb);
221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  matrix(b,*m,*n,*ldb).setZero();
222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(SIDE(*side)==LEFT)
224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    internal::gemm_blocking_space<ColMajor,Scalar,Scalar,Dynamic,Dynamic,Dynamic,4> blocking(*m,*n,*m);
226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[code](*m, *n, *m, a, *lda, tmp.data(), tmp.outerStride(), b, *ldb, alpha, blocking);
227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else
229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    internal::gemm_blocking_space<ColMajor,Scalar,Scalar,Dynamic,Dynamic,Dynamic,4> blocking(*m,*n,*n);
231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[code](*m, *n, *n, tmp.data(), tmp.outerStride(), a, *lda, b, *ldb, alpha, blocking);
232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return 1;
234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// c = alpha*a*b + beta*c  for side = 'L'or'l'
237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// c = alpha*b*a + beta*c  for side = 'R'or'r
238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathint EIGEN_BLAS_FUNC(symm)(char *side, char *uplo, int *m, int *n, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pb, int *ldb, RealScalar *pbeta, RealScalar *pc, int *ldc)
239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//   std::cerr << "in symm " << *side << " " << *uplo << " " << *m << "x" << *n << " lda:" << *lda << " ldb:" << *ldb << " ldc:" << *ldc << " alpha:" << *palpha << " beta:" << *pbeta << "\n";
241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* a = reinterpret_cast<Scalar*>(pa);
242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* b = reinterpret_cast<Scalar*>(pb);
243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* c = reinterpret_cast<Scalar*>(pc);
244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar alpha = *reinterpret_cast<Scalar*>(palpha);
245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar beta  = *reinterpret_cast<Scalar*>(pbeta);
246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int info = 0;
248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(SIDE(*side)==INVALID)                                            info = 1;
249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(UPLO(*uplo)==INVALID)                                       info = 2;
250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*m<0)                                                       info = 3;
251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*n<0)                                                       info = 4;
252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*lda<std::max(1,(SIDE(*side)==LEFT)?*m:*n))                 info = 7;
253c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*ldb<std::max(1,*m))                                        info = 9;
254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*ldc<std::max(1,*m))                                        info = 12;
255c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(info)
256c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return xerbla_(SCALAR_SUFFIX_UP"SYMM ",&info,6);
257c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(beta!=Scalar(1))
259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(beta==Scalar(0)) matrix(c, *m, *n, *ldc).setZero();
261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else                matrix(c, *m, *n, *ldc) *= beta;
262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(*m==0 || *n==0)
265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
266c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return 1;
267c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
268c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
269c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  #if ISCOMPLEX
270c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // FIXME add support for symmetric complex matrix
271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int size = (SIDE(*side)==LEFT) ? (*m) : (*n);
272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Matrix<Scalar,Dynamic,Dynamic,ColMajor> matA(size,size);
273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(UPLO(*uplo)==UP)
274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    matA.triangularView<Upper>() = matrix(a,size,size,*lda);
276c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    matA.triangularView<Lower>() = matrix(a,size,size,*lda).transpose();
277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
278c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(UPLO(*uplo)==LO)
279c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
280c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    matA.triangularView<Lower>() = matrix(a,size,size,*lda);
281c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    matA.triangularView<Upper>() = matrix(a,size,size,*lda).transpose();
282c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
283c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(SIDE(*side)==LEFT)
284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    matrix(c, *m, *n, *ldc) += alpha * matA * matrix(b, *m, *n, *ldb);
285c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(SIDE(*side)==RIGHT)
286c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    matrix(c, *m, *n, *ldc) += alpha * matrix(b, *m, *n, *ldb) * matA;
287c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  #else
288c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(SIDE(*side)==LEFT)
289c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(UPLO(*uplo)==UP)       internal::product_selfadjoint_matrix<Scalar, DenseIndex, RowMajor,true,false, ColMajor,false,false, ColMajor>::run(*m, *n, a, *lda, b, *ldb, c, *ldc, alpha);
290c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else if(UPLO(*uplo)==LO)  internal::product_selfadjoint_matrix<Scalar, DenseIndex, ColMajor,true,false, ColMajor,false,false, ColMajor>::run(*m, *n, a, *lda, b, *ldb, c, *ldc, alpha);
291c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else                      return 0;
292c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(SIDE(*side)==RIGHT)
293c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(UPLO(*uplo)==UP)       internal::product_selfadjoint_matrix<Scalar, DenseIndex, ColMajor,false,false, RowMajor,true,false, ColMajor>::run(*m, *n, b, *ldb, a, *lda, c, *ldc, alpha);
294c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else if(UPLO(*uplo)==LO)  internal::product_selfadjoint_matrix<Scalar, DenseIndex, ColMajor,false,false, ColMajor,true,false, ColMajor>::run(*m, *n, b, *ldb, a, *lda, c, *ldc, alpha);
295c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else                      return 0;
296c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else
297c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return 0;
298c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  #endif
299c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
300c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return 0;
301c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
302c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
303c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// c = alpha*a*a' + beta*c  for op = 'N'or'n'
304c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// c = alpha*a'*a + beta*c  for op = 'T'or't','C'or'c'
305c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathint EIGEN_BLAS_FUNC(syrk)(char *uplo, char *op, int *n, int *k, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pbeta, RealScalar *pc, int *ldc)
306c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
307c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//   std::cerr << "in syrk " << *uplo << " " << *op << " " << *n << " " << *k << " " << *palpha << " " << *lda << " " << *pbeta << " " << *ldc << "\n";
3087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  #if !ISCOMPLEX
3097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  typedef void (*functype)(DenseIndex, DenseIndex, const Scalar *, DenseIndex, const Scalar *, DenseIndex, Scalar *, DenseIndex, const Scalar&);
310c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static functype func[8];
311c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
312c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static bool init = false;
313c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(!init)
314c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
315c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(int k=0; k<8; ++k)
316c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      func[k] = 0;
317c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
318c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (UP << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,ColMajor,false,Scalar,RowMajor,ColMajor,Conj, Upper>::run);
319c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (UP << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,RowMajor,false,Scalar,ColMajor,ColMajor,Conj, Upper>::run);
320c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (UP << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,RowMajor,Conj, Scalar,ColMajor,ColMajor,false,Upper>::run);
321c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
322c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (LO << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,ColMajor,false,Scalar,RowMajor,ColMajor,Conj, Lower>::run);
323c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[TR    | (LO << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,RowMajor,false,Scalar,ColMajor,ColMajor,Conj, Lower>::run);
324c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (LO << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,RowMajor,Conj, Scalar,ColMajor,ColMajor,false,Lower>::run);
325c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
326c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    init = true;
327c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
3287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  #endif
329c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
330c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* a = reinterpret_cast<Scalar*>(pa);
331c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* c = reinterpret_cast<Scalar*>(pc);
332c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar alpha = *reinterpret_cast<Scalar*>(palpha);
333c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar beta  = *reinterpret_cast<Scalar*>(pbeta);
334c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
335c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int info = 0;
336c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(UPLO(*uplo)==INVALID)                                            info = 1;
337c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(OP(*op)==INVALID)                                           info = 2;
338c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*n<0)                                                       info = 3;
339c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*k<0)                                                       info = 4;
340c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*lda<std::max(1,(OP(*op)==NOTR)?*n:*k))                     info = 7;
341c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*ldc<std::max(1,*n))                                        info = 10;
342c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(info)
343c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return xerbla_(SCALAR_SUFFIX_UP"SYRK ",&info,6);
344c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
345c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(beta!=Scalar(1))
346c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
347c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(UPLO(*uplo)==UP)
348c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if(beta==Scalar(0)) matrix(c, *n, *n, *ldc).triangularView<Upper>().setZero();
349c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else                matrix(c, *n, *n, *ldc).triangularView<Upper>() *= beta;
350c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else
351c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if(beta==Scalar(0)) matrix(c, *n, *n, *ldc).triangularView<Lower>().setZero();
352c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else                matrix(c, *n, *n, *ldc).triangularView<Lower>() *= beta;
353c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
354c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
355c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  #if ISCOMPLEX
356c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // FIXME add support for symmetric complex matrix
357c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(UPLO(*uplo)==UP)
358c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
359c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(OP(*op)==NOTR)
360c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      matrix(c, *n, *n, *ldc).triangularView<Upper>() += alpha * matrix(a,*n,*k,*lda) * matrix(a,*n,*k,*lda).transpose();
361c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else
362c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      matrix(c, *n, *n, *ldc).triangularView<Upper>() += alpha * matrix(a,*k,*n,*lda).transpose() * matrix(a,*k,*n,*lda);
363c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
364c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else
365c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
366c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(OP(*op)==NOTR)
367c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      matrix(c, *n, *n, *ldc).triangularView<Lower>() += alpha * matrix(a,*n,*k,*lda) * matrix(a,*n,*k,*lda).transpose();
368c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else
369c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      matrix(c, *n, *n, *ldc).triangularView<Lower>() += alpha * matrix(a,*k,*n,*lda).transpose() * matrix(a,*k,*n,*lda);
370c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
371c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  #else
372c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int code = OP(*op) | (UPLO(*uplo) << 2);
373c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  func[code](*n, *k, a, *lda, a, *lda, c, *ldc, alpha);
374c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  #endif
375c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
376c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return 0;
377c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
378c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
379c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// c = alpha*a*b' + alpha*b*a' + beta*c  for op = 'N'or'n'
380c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// c = alpha*a'*b + alpha*b'*a + beta*c  for op = 'T'or't'
381c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathint EIGEN_BLAS_FUNC(syr2k)(char *uplo, char *op, int *n, int *k, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pb, int *ldb, RealScalar *pbeta, RealScalar *pc, int *ldc)
382c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
383c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* a = reinterpret_cast<Scalar*>(pa);
384c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* b = reinterpret_cast<Scalar*>(pb);
385c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* c = reinterpret_cast<Scalar*>(pc);
386c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar alpha = *reinterpret_cast<Scalar*>(palpha);
387c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar beta  = *reinterpret_cast<Scalar*>(pbeta);
388c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
389c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int info = 0;
390c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(UPLO(*uplo)==INVALID)                                            info = 1;
391c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(OP(*op)==INVALID)                                           info = 2;
392c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*n<0)                                                       info = 3;
393c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*k<0)                                                       info = 4;
394c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*lda<std::max(1,(OP(*op)==NOTR)?*n:*k))                     info = 7;
395c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*ldb<std::max(1,(OP(*op)==NOTR)?*n:*k))                     info = 9;
396c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*ldc<std::max(1,*n))                                        info = 12;
397c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(info)
398c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return xerbla_(SCALAR_SUFFIX_UP"SYR2K",&info,6);
399c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
400c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(beta!=Scalar(1))
401c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
402c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(UPLO(*uplo)==UP)
403c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if(beta==Scalar(0)) matrix(c, *n, *n, *ldc).triangularView<Upper>().setZero();
404c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else                matrix(c, *n, *n, *ldc).triangularView<Upper>() *= beta;
405c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else
406c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if(beta==Scalar(0)) matrix(c, *n, *n, *ldc).triangularView<Lower>().setZero();
407c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else                matrix(c, *n, *n, *ldc).triangularView<Lower>() *= beta;
408c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
409c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
410c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(*k==0)
411c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return 1;
412c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
413c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(OP(*op)==NOTR)
414c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
415c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(UPLO(*uplo)==UP)
416c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
417c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      matrix(c, *n, *n, *ldc).triangularView<Upper>()
418c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        += alpha *matrix(a, *n, *k, *lda)*matrix(b, *n, *k, *ldb).transpose()
419c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        +  alpha*matrix(b, *n, *k, *ldb)*matrix(a, *n, *k, *lda).transpose();
420c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
421c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else if(UPLO(*uplo)==LO)
422c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      matrix(c, *n, *n, *ldc).triangularView<Lower>()
423c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        += alpha*matrix(a, *n, *k, *lda)*matrix(b, *n, *k, *ldb).transpose()
424c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        +  alpha*matrix(b, *n, *k, *ldb)*matrix(a, *n, *k, *lda).transpose();
425c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
426c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(OP(*op)==TR || OP(*op)==ADJ)
427c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
428c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(UPLO(*uplo)==UP)
429c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      matrix(c, *n, *n, *ldc).triangularView<Upper>()
430c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        += alpha*matrix(a, *k, *n, *lda).transpose()*matrix(b, *k, *n, *ldb)
431c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        +  alpha*matrix(b, *k, *n, *ldb).transpose()*matrix(a, *k, *n, *lda);
432c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else if(UPLO(*uplo)==LO)
433c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      matrix(c, *n, *n, *ldc).triangularView<Lower>()
434c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        += alpha*matrix(a, *k, *n, *lda).transpose()*matrix(b, *k, *n, *ldb)
435c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        +  alpha*matrix(b, *k, *n, *ldb).transpose()*matrix(a, *k, *n, *lda);
436c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
437c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
438c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return 0;
439c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
440c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
441c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
442c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#if ISCOMPLEX
443c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
444c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// c = alpha*a*b + beta*c  for side = 'L'or'l'
445c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// c = alpha*b*a + beta*c  for side = 'R'or'r
446c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathint EIGEN_BLAS_FUNC(hemm)(char *side, char *uplo, int *m, int *n, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pb, int *ldb, RealScalar *pbeta, RealScalar *pc, int *ldc)
447c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
448c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* a = reinterpret_cast<Scalar*>(pa);
449c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* b = reinterpret_cast<Scalar*>(pb);
450c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* c = reinterpret_cast<Scalar*>(pc);
451c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar alpha = *reinterpret_cast<Scalar*>(palpha);
452c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar beta  = *reinterpret_cast<Scalar*>(pbeta);
453c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
454c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//   std::cerr << "in hemm " << *side << " " << *uplo << " " << *m << " " << *n << " " << alpha << " " << *lda << " " << beta << " " << *ldc << "\n";
455c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
456c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int info = 0;
457c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(SIDE(*side)==INVALID)                                            info = 1;
458c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(UPLO(*uplo)==INVALID)                                       info = 2;
459c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*m<0)                                                       info = 3;
460c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*n<0)                                                       info = 4;
461c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*lda<std::max(1,(SIDE(*side)==LEFT)?*m:*n))                 info = 7;
462c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*ldb<std::max(1,*m))                                        info = 9;
463c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*ldc<std::max(1,*m))                                        info = 12;
464c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(info)
465c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return xerbla_(SCALAR_SUFFIX_UP"HEMM ",&info,6);
466c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
467c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(beta==Scalar(0))       matrix(c, *m, *n, *ldc).setZero();
468c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(beta!=Scalar(1))  matrix(c, *m, *n, *ldc) *= beta;
469c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
470c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(*m==0 || *n==0)
471c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
472c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return 1;
473c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
474c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
475c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(SIDE(*side)==LEFT)
476c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
477c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(UPLO(*uplo)==UP)       internal::product_selfadjoint_matrix<Scalar,DenseIndex,RowMajor,true,Conj,  ColMajor,false,false, ColMajor>
478c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                ::run(*m, *n, a, *lda, b, *ldb, c, *ldc, alpha);
479c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else if(UPLO(*uplo)==LO)  internal::product_selfadjoint_matrix<Scalar,DenseIndex,ColMajor,true,false, ColMajor,false,false, ColMajor>
480c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                ::run(*m, *n, a, *lda, b, *ldb, c, *ldc, alpha);
481c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else                      return 0;
482c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
483c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(SIDE(*side)==RIGHT)
484c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
485c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(UPLO(*uplo)==UP)       matrix(c,*m,*n,*ldc) += alpha * matrix(b,*m,*n,*ldb) * matrix(a,*n,*n,*lda).selfadjointView<Upper>();/*internal::product_selfadjoint_matrix<Scalar,DenseIndex,ColMajor,false,false, RowMajor,true,Conj,  ColMajor>
486c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                ::run(*m, *n, b, *ldb, a, *lda, c, *ldc, alpha);*/
487c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else if(UPLO(*uplo)==LO)  internal::product_selfadjoint_matrix<Scalar,DenseIndex,ColMajor,false,false, ColMajor,true,false, ColMajor>
488c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                ::run(*m, *n, b, *ldb, a, *lda, c, *ldc, alpha);
489c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else                      return 0;
490c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
491c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else
492c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
493c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return 0;
494c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
495c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
496c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return 0;
497c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
498c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
499c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// c = alpha*a*conj(a') + beta*c  for op = 'N'or'n'
500c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// c = alpha*conj(a')*a + beta*c  for op  = 'C'or'c'
501c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathint EIGEN_BLAS_FUNC(herk)(char *uplo, char *op, int *n, int *k, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pbeta, RealScalar *pc, int *ldc)
502c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
5037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  typedef void (*functype)(DenseIndex, DenseIndex, const Scalar *, DenseIndex, const Scalar *, DenseIndex, Scalar *, DenseIndex, const Scalar&);
504c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static functype func[8];
505c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
506c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static bool init = false;
507c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(!init)
508c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
509c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(int k=0; k<8; ++k)
510c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      func[k] = 0;
511c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
512c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (UP << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,ColMajor,false,Scalar,RowMajor,Conj, ColMajor,Upper>::run);
513c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (UP << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,RowMajor,Conj, Scalar,ColMajor,false,ColMajor,Upper>::run);
514c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
515c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[NOTR  | (LO << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,ColMajor,false,Scalar,RowMajor,Conj, ColMajor,Lower>::run);
516c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[ADJ   | (LO << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,RowMajor,Conj, Scalar,ColMajor,false,ColMajor,Lower>::run);
517c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
518c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    init = true;
519c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
520c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
521c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* a = reinterpret_cast<Scalar*>(pa);
522c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* c = reinterpret_cast<Scalar*>(pc);
523c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  RealScalar alpha = *palpha;
524c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  RealScalar beta  = *pbeta;
525c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
526c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//   std::cerr << "in herk " << *uplo << " " << *op << " " << *n << " " << *k << " " << alpha << " " << *lda << " " << beta << " " << *ldc << "\n";
527c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
528c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int info = 0;
529c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(UPLO(*uplo)==INVALID)                                            info = 1;
530c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if((OP(*op)==INVALID) || (OP(*op)==TR))                        info = 2;
531c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*n<0)                                                       info = 3;
532c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*k<0)                                                       info = 4;
533c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*lda<std::max(1,(OP(*op)==NOTR)?*n:*k))                     info = 7;
534c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*ldc<std::max(1,*n))                                        info = 10;
535c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(info)
536c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return xerbla_(SCALAR_SUFFIX_UP"HERK ",&info,6);
537c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
538c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int code = OP(*op) | (UPLO(*uplo) << 2);
539c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
540c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(beta!=RealScalar(1))
541c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
542c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(UPLO(*uplo)==UP)
543c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if(beta==Scalar(0)) matrix(c, *n, *n, *ldc).triangularView<Upper>().setZero();
544c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else                matrix(c, *n, *n, *ldc).triangularView<StrictlyUpper>() *= beta;
545c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else
546c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if(beta==Scalar(0)) matrix(c, *n, *n, *ldc).triangularView<Lower>().setZero();
547c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else                matrix(c, *n, *n, *ldc).triangularView<StrictlyLower>() *= beta;
548c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
549c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(beta!=Scalar(0))
550c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
551c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      matrix(c, *n, *n, *ldc).diagonal().real() *= beta;
552c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      matrix(c, *n, *n, *ldc).diagonal().imag().setZero();
553c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
554c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
555c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
556c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(*k>0 && alpha!=RealScalar(0))
557c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
558c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    func[code](*n, *k, a, *lda, a, *lda, c, *ldc, alpha);
559c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    matrix(c, *n, *n, *ldc).diagonal().imag().setZero();
560c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
561c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return 0;
562c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
563c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
564c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// c = alpha*a*conj(b') + conj(alpha)*b*conj(a') + beta*c,  for op = 'N'or'n'
565c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// c = alpha*conj(a')*b + conj(alpha)*conj(b')*a + beta*c,  for op = 'C'or'c'
566c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathint EIGEN_BLAS_FUNC(her2k)(char *uplo, char *op, int *n, int *k, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pb, int *ldb, RealScalar *pbeta, RealScalar *pc, int *ldc)
567c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
568c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* a = reinterpret_cast<Scalar*>(pa);
569c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* b = reinterpret_cast<Scalar*>(pb);
570c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar* c = reinterpret_cast<Scalar*>(pc);
571c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  Scalar alpha = *reinterpret_cast<Scalar*>(palpha);
572c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  RealScalar beta  = *pbeta;
573c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
574c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  int info = 0;
575c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(UPLO(*uplo)==INVALID)                                            info = 1;
576c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if((OP(*op)==INVALID) || (OP(*op)==TR))                        info = 2;
577c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*n<0)                                                       info = 3;
578c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*k<0)                                                       info = 4;
579c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*lda<std::max(1,(OP(*op)==NOTR)?*n:*k))                     info = 7;
580c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*lda<std::max(1,(OP(*op)==NOTR)?*n:*k))                     info = 9;
581c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*ldc<std::max(1,*n))                                        info = 12;
582c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(info)
583c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return xerbla_(SCALAR_SUFFIX_UP"HER2K",&info,6);
584c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
585c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(beta!=RealScalar(1))
586c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
587c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(UPLO(*uplo)==UP)
588c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if(beta==Scalar(0)) matrix(c, *n, *n, *ldc).triangularView<Upper>().setZero();
589c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else                matrix(c, *n, *n, *ldc).triangularView<StrictlyUpper>() *= beta;
590c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else
591c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if(beta==Scalar(0)) matrix(c, *n, *n, *ldc).triangularView<Lower>().setZero();
592c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else                matrix(c, *n, *n, *ldc).triangularView<StrictlyLower>() *= beta;
593c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
594c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(beta!=Scalar(0))
595c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
596c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      matrix(c, *n, *n, *ldc).diagonal().real() *= beta;
597c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      matrix(c, *n, *n, *ldc).diagonal().imag().setZero();
598c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
599c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
600c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(*k>0 && alpha!=Scalar(0))
601c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    matrix(c, *n, *n, *ldc).diagonal().imag().setZero();
602c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
603c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(*k==0)
604c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    return 1;
605c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
606c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(OP(*op)==NOTR)
607c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
608c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(UPLO(*uplo)==UP)
609c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
610c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      matrix(c, *n, *n, *ldc).triangularView<Upper>()
6117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        +=            alpha *matrix(a, *n, *k, *lda)*matrix(b, *n, *k, *ldb).adjoint()
6127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        +  numext::conj(alpha)*matrix(b, *n, *k, *ldb)*matrix(a, *n, *k, *lda).adjoint();
613c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
614c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else if(UPLO(*uplo)==LO)
615c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      matrix(c, *n, *n, *ldc).triangularView<Lower>()
616c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        += alpha*matrix(a, *n, *k, *lda)*matrix(b, *n, *k, *ldb).adjoint()
6177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        +  numext::conj(alpha)*matrix(b, *n, *k, *ldb)*matrix(a, *n, *k, *lda).adjoint();
618c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
619c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else if(OP(*op)==ADJ)
620c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
621c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(UPLO(*uplo)==UP)
622c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      matrix(c, *n, *n, *ldc).triangularView<Upper>()
6237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        +=             alpha*matrix(a, *k, *n, *lda).adjoint()*matrix(b, *k, *n, *ldb)
6247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        +  numext::conj(alpha)*matrix(b, *k, *n, *ldb).adjoint()*matrix(a, *k, *n, *lda);
625c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else if(UPLO(*uplo)==LO)
626c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      matrix(c, *n, *n, *ldc).triangularView<Lower>()
6277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        +=             alpha*matrix(a, *k, *n, *lda).adjoint()*matrix(b, *k, *n, *ldb)
6287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        +  numext::conj(alpha)*matrix(b, *k, *n, *ldb).adjoint()*matrix(a, *k, *n, *lda);
629c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
630c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
631c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return 1;
632c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
633c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
634c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // ISCOMPLEX
635