// Copyright (C) 2001-2009 Vivien Mallet
//
// This file is part of the linear-algebra library Seldon,
// http://seldon.sourceforge.net/.
//
// Seldon 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 2.1 of the License, or (at your option)
// any later version.
//
// Seldon 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 Seldon. If not, see http://www.gnu.org/licenses/.


#ifndef SELDON_FILE_BLAS_3_CXX

/*
  Functions included in this file:

  xGEMM   (MltAdd)
  xSYMM   (MltAdd)
  xHEMM   (MltAdd)
  xTRMM   (Mlt)
  xTRSM   (Solve)
*/


extern "C"
{
#include "cblas.h"
}

namespace Seldon
{


 
////////////
 
// MltAdd //


 
/*** ColMajor and NoTrans ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const float alpha,
             
const Matrix<float, Prop0, ColMajor, Allocator0>& A,
             
const Matrix<float, Prop1, ColMajor, Allocator1>& B,
             
const float beta,
             
Matrix<float, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(A, B, C, "MltAdd(alpha, A, B, beta, C)");
#endif

    cblas_sgemm
(CblasColMajor, CblasNoTrans, CblasNoTrans,
                C
.GetM(), C.GetN(), A.GetN(),
                alpha
, A.GetData(), A.GetLD(), B.GetData(), B.GetLD(),
                beta
, C.GetData(), C.GetLD());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const double alpha,
             
const Matrix<double, Prop0, ColMajor, Allocator0>& A,
             
const Matrix<double, Prop1, ColMajor, Allocator1>& B,
             
const double beta,
             
Matrix<double, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(A, B, C, "MltAdd(alpha, A, B, beta, C)");
#endif

    cblas_dgemm
(CblasColMajor, CblasNoTrans, CblasNoTrans,
                C
.GetM(), C.GetN(), A.GetN(),
                alpha
, A.GetData(), A.GetLD(), B.GetData(), B.GetLD(),
                beta
, C.GetData(), C.GetLD());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const complex<float> alpha,
             
const Matrix<complex<float>, Prop0, ColMajor, Allocator0>& A,
             
const Matrix<complex<float>, Prop1, ColMajor, Allocator1>& B,
             
const complex<float> beta,
             
Matrix<complex<float>, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(A, B, C, "MltAdd(alpha, A, B, beta, C)");
#endif

    cblas_cgemm
(CblasColMajor, CblasNoTrans, CblasNoTrans,
                C
.GetM(), C.GetN(), A.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetLD(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetLD(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetLD());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const complex<double> alpha,
             
const Matrix<complex<double>, Prop0, ColMajor, Allocator0>& A,
             
const Matrix<complex<double>, Prop1, ColMajor, Allocator1>& B,
             
const complex<double> beta,
             
Matrix<complex<double>, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(A, B, C, "MltAdd(alpha, A, B, beta, C)");
#endif

    cblas_zgemm
(CblasColMajor, CblasNoTrans, CblasNoTrans,
                C
.GetM(), C.GetN(), A.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetLD(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetLD(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetLD());
 
}


 
/*** ColMajor and TransA, TransB ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const float alpha,
             
const SeldonTranspose& TransA,
             
const Matrix<float, Prop0, ColMajor, Allocator0>& A,
             
const SeldonTranspose& TransB,
             
const Matrix<float, Prop1, ColMajor, Allocator1>& B,
             
const float beta,
             
Matrix<float, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(TransA, A, TransB, B, C,
             
"MltAdd(alpha, TransA, A, TransB, B, beta, C)");
#endif

    cblas_sgemm
(CblasColMajor, TransA, TransB, C.GetM(), C.GetN(),
                A
.GetN(TransA), alpha, A.GetData(), A.GetLD(),
                B
.GetData(), B.GetLD(), beta, C.GetData(), C.GetLD());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const double alpha,
             
const SeldonTranspose& TransA,
             
const Matrix<double, Prop0, ColMajor, Allocator0>& A,
             
const SeldonTranspose& TransB,
             
const Matrix<double, Prop1, ColMajor, Allocator1>& B,
             
const double beta,
             
Matrix<double, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(TransA, A, TransB, B, C,
             
"MltAdd(alpha, TransA, A, TransB, B, beta, C)");
#endif

    cblas_dgemm
(CblasColMajor, TransA, TransB, C.GetM(), C.GetN(),
                A
.GetN(TransA), alpha, A.GetData(), A.GetLD(),
                B
.GetData(), B.GetLD(), beta, C.GetData(), C.GetLD());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const complex<float> alpha,
             
const SeldonTranspose& TransA,
             
const Matrix<complex<float>, Prop0, ColMajor, Allocator0>& A,
             
const SeldonTranspose& TransB,
             
const Matrix<complex<float>, Prop1, ColMajor, Allocator1>& B,
             
const complex<float> beta,
             
Matrix<complex<float>, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(TransA, A, TransB, B, C,
             
"MltAdd(alpha, TransA, A, TransB, B, beta, C)");
#endif

    cblas_cgemm
(CblasColMajor, TransA, TransB, C.GetM(), C.GetN(),
                A
.GetN(TransA), reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetLD(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetLD(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetLD());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const complex<double> alpha,
             
const SeldonTranspose& TransA,
             
const Matrix<complex<double>, Prop0, ColMajor, Allocator0>& A,
             
const SeldonTranspose& TransB,
             
const Matrix<complex<double>, Prop1, ColMajor, Allocator1>& B,
             
const complex<double> beta,
             
Matrix<complex<double>, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(TransA, A, TransB, B, C,
             
"MltAdd(alpha, TransA, A, TransB, B, beta, C)");
#endif

    cblas_zgemm
(CblasColMajor, TransA, TransB, C.GetM(), C.GetN(),
                A
.GetN(TransA), reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetLD(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetLD(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetLD());
 
}


 
/*** RowMajor and NoTrans ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const float alpha,
             
const Matrix<float, Prop0, RowMajor, Allocator0>& A,
             
const Matrix<float, Prop1, RowMajor, Allocator1>& B,
             
const float beta,
             
Matrix<float, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(A, B, C, "MltAdd(alpha, A, B, beta, C)");
#endif

    cblas_sgemm
(CblasRowMajor, CblasNoTrans, CblasNoTrans,
                C
.GetM(), C.GetN(), A.GetN(),
                alpha
, A.GetData(), A.GetLD(), B.GetData(), B.GetLD(),
                beta
, C.GetData(), C.GetLD());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const double alpha,
             
const Matrix<double, Prop0, RowMajor, Allocator0>& A,
             
const Matrix<double, Prop1, RowMajor, Allocator1>& B,
             
const double beta,
             
Matrix<double, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(A, B, C, "MltAdd(alpha, A, B, beta, C)");
#endif

    cblas_dgemm
(CblasRowMajor, CblasNoTrans, CblasNoTrans,
                C
.GetM(), C.GetN(), A.GetN(),
                alpha
, A.GetData(), A.GetLD(), B.GetData(), B.GetLD(),
                beta
, C.GetData(), C.GetLD());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const complex<float> alpha,
             
const Matrix<complex<float>, Prop0, RowMajor, Allocator0>& A,
             
const Matrix<complex<float>, Prop1, RowMajor, Allocator1>& B,
             
const complex<float> beta,
             
Matrix<complex<float>, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(A, B, C, "MltAdd(alpha, A, B, beta, C)");
#endif

    cblas_cgemm
(CblasRowMajor, CblasNoTrans, CblasNoTrans,
                C
.GetM(), C.GetN(), A.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetLD(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetLD(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetLD());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const complex<double> alpha,
             
const Matrix<complex<double>, Prop0, RowMajor, Allocator0>& A,
             
const Matrix<complex<double>, Prop1, RowMajor, Allocator1>& B,
             
const complex<double> beta,
             
Matrix<complex<double>, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(A, B, C, "MltAdd(alpha, A, B, beta, C)");
#endif

    cblas_zgemm
(CblasRowMajor, CblasNoTrans, CblasNoTrans,
                C
.GetM(), C.GetN(), A.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetLD(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetLD(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetLD());
 
}


 
/*** RowMajor and TransA, TransB ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const float alpha,
             
const SeldonTranspose& TransA,
             
const Matrix<float, Prop0, RowMajor, Allocator0>& A,
             
const SeldonTranspose& TransB,
             
const Matrix<float, Prop1, RowMajor, Allocator1>& B,
             
const float beta,
             
Matrix<float, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(TransA, A, TransB, B, C,
             
"MltAdd(alpha, TransA, A, TransB, B, beta, C)");
#endif

    cblas_sgemm
(CblasRowMajor, TransA, TransB, C.GetM(), C.GetN(),
                A
.GetN(TransA), alpha, A.GetData(), A.GetLD(),
                B
.GetData(), B.GetLD(), beta, C.GetData(), C.GetLD());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const double alpha,
             
const SeldonTranspose& TransA,
             
const Matrix<double, Prop0, RowMajor, Allocator0>& A,
             
const SeldonTranspose& TransB,
             
const Matrix<double, Prop1, RowMajor, Allocator1>& B,
             
const double beta,
             
Matrix<double, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(TransA, A, TransB, B, C,
             
"MltAdd(alpha, TransA, A, TransB, B, beta, C)");
#endif

    cblas_dgemm
(CblasRowMajor, TransA, TransB, C.GetM(), C.GetN(),
                A
.GetN(TransA), alpha, A.GetData(), A.GetLD(),
                B
.GetData(), B.GetLD(), beta, C.GetData(), C.GetLD());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const complex<float> alpha,
             
const SeldonTranspose& TransA,
             
const Matrix<complex<float>, Prop0, RowMajor, Allocator0>& A,
             
const SeldonTranspose& TransB,
             
const Matrix<complex<float>, Prop1, RowMajor, Allocator1>& B,
             
const complex<float> beta,
             
Matrix<complex<float>, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(TransA, A, TransB, B, C,
             
"MltAdd(alpha, TransA, A, TransB, B, beta, C)");
#endif

    cblas_cgemm
(CblasRowMajor, TransA, TransB, C.GetM(), C.GetN(),
                A
.GetN(TransA), reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetLD(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetLD(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetLD());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const complex<double> alpha,
             
const SeldonTranspose& TransA,
             
const Matrix<complex<double>, Prop0, RowMajor, Allocator0>& A,
             
const SeldonTranspose& TransB,
             
const Matrix<complex<double>, Prop1, RowMajor, Allocator1>& B,
             
const complex<double> beta,
             
Matrix<complex<double>, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(TransA, A, TransB, B, C,
             
"MltAdd(alpha, TransA, A, TransB, B, beta, C)");
#endif

    cblas_zgemm
(CblasRowMajor, TransA, TransB, C.GetM(), C.GetN(),
                A
.GetN(TransA), reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetLD(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetLD(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetLD());
 
}


 
// MltAdd //
 
////////////



 
////////////
 
// MltAdd //


 
/*** ColSym and Upper ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const float alpha,
             
const Matrix<float, Prop0, ColSym, Allocator0>& A,
             
const Matrix<float, Prop1, ColMajor, Allocator1>& B,
             
const float beta,
             
Matrix<float, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, A, B, beta, C)");
#endif

    cblas_ssymm
(CblasColMajor, Side, CblasUpper,
                C
.GetM(), C.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM(),
                beta
, C.GetData(), C.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const double alpha,
             
const Matrix<double, Prop0, ColSym, Allocator0>& A,
             
const Matrix<double, Prop1, ColMajor, Allocator1>& B,
             
const double beta,
             
Matrix<double, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, A, B, beta, C)");
#endif

    cblas_dsymm
(CblasColMajor, Side, CblasUpper,
                C
.GetM(), C.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM(),
                beta
, C.GetData(), C.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const complex<float> alpha,
             
const Matrix<complex<float>, Prop0, ColSym, Allocator0>& A,
             
const Matrix<complex<float>, Prop1, ColMajor, Allocator1>& B,
             
const complex<float> beta,
             
Matrix<complex<float>, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, A, B, beta, C)");
#endif

    cblas_csymm
(CblasColMajor, Side, CblasUpper,
                C
.GetM(), C.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetM(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const complex<double> alpha,
             
const Matrix<complex<double>, Prop0, ColSym, Allocator0>& A,
             
const Matrix<complex<double>, Prop1, ColMajor, Allocator1>& B,
             
const complex<double> beta,
             
Matrix<complex<double>, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, A, B, beta, C)");
#endif

    cblas_zsymm
(CblasColMajor, Side, CblasUpper,
                C
.GetM(), C.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetM(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetM());
 
}


 
/*** ColSym and UpLo ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const float alpha,
             
const SeldonUplo& Uplo,
             
const Matrix<float, Prop0, ColSym, Allocator0>& A,
             
const Matrix<float, Prop1, ColMajor, Allocator1>& B,
             
const float beta,
             
Matrix<float, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, uplo, A, B, beta, C)");
#endif

    cblas_ssymm
(CblasColMajor, Side, Uplo,
                C
.GetM(), C.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM(),
                beta
, C.GetData(), C.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const double alpha,
             
const SeldonUplo& Uplo,
             
const Matrix<double, Prop0, ColSym, Allocator0>& A,
             
const Matrix<double, Prop1, ColMajor, Allocator1>& B,
             
const double beta,
             
Matrix<double, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, uplo, A, B, beta, C)");
#endif

    cblas_dsymm
(CblasColMajor, Side, Uplo,
                C
.GetM(), C.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM(),
                beta
, C.GetData(), C.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const complex<float> alpha,
             
const SeldonUplo& Uplo,
             
const Matrix<complex<float>, Prop0, ColSym, Allocator0>& A,
             
const Matrix<complex<float>, Prop1, ColMajor, Allocator1>& B,
             
const complex<float> beta,
             
Matrix<complex<float>, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, uplo, A, B, beta, C)");
#endif

    cblas_csymm
(CblasColMajor, Side, Uplo,
                C
.GetM(), C.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetM(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const complex<double> alpha,
             
const SeldonUplo& Uplo,
             
const Matrix<complex<double>, Prop0, ColSym, Allocator0>& A,
             
const Matrix<complex<double>, Prop1, ColMajor, Allocator1>& B,
             
const complex<double> beta,
             
Matrix<complex<double>, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, uplo, A, B, beta, C)");
#endif

    cblas_zsymm
(CblasColMajor, Side, Uplo,
                C
.GetM(), C.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetM(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetM());
 
}


 
/*** RowSym and Upper ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const float alpha,
             
const Matrix<float, Prop0, RowSym, Allocator0>& A,
             
const Matrix<float, Prop1, RowMajor, Allocator1>& B,
             
const float beta,
             
Matrix<float, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, A, B, beta, C)");
#endif

    cblas_ssymm
(CblasRowMajor, Side, CblasUpper,
                C
.GetM(), C.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetN(),
                beta
, C.GetData(), C.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const double alpha,
             
const Matrix<double, Prop0, RowSym, Allocator0>& A,
             
const Matrix<double, Prop1, RowMajor, Allocator1>& B,
             
const double beta,
             
Matrix<double, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, A, B, beta, C)");
#endif

    cblas_dsymm
(CblasRowMajor, Side, CblasUpper,
                C
.GetM(), C.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetN(),
                beta
, C.GetData(), C.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const complex<float> alpha,
             
const Matrix<complex<float>, Prop0, RowSym, Allocator0>& A,
             
const Matrix<complex<float>, Prop1, RowMajor, Allocator1>& B,
             
const complex<float> beta,
             
Matrix<complex<float>, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, A, B, beta, C)");
#endif

    cblas_csymm
(CblasRowMajor, Side, CblasUpper,
                C
.GetM(), C.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetN(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const complex<double> alpha,
             
const Matrix<complex<double>, Prop0, RowSym, Allocator0>& A,
             
const Matrix<complex<double>, Prop1, RowMajor, Allocator1>& B,
             
const complex<double> beta,
             
Matrix<complex<double>, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, A, B, beta, C)");
#endif

    cblas_zsymm
(CblasRowMajor, Side, CblasUpper,
                C
.GetM(), C.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetN(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetN());
 
}


 
/*** RowSym and UpLo ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const float alpha,
             
const SeldonUplo& Uplo,
             
const Matrix<float, Prop0, RowSym, Allocator0>& A,
             
const Matrix<float, Prop1, RowMajor, Allocator1>& B,
             
const float beta,
             
Matrix<float, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, uplo, A, B, beta, C)");
#endif

    cblas_ssymm
(CblasRowMajor, Side, Uplo,
                C
.GetM(), C.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetN(),
                beta
, C.GetData(), C.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const double alpha,
             
const SeldonUplo& Uplo,
             
const Matrix<double, Prop0, RowSym, Allocator0>& A,
             
const Matrix<double, Prop1, RowMajor, Allocator1>& B,
             
const double beta,
             
Matrix<double, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, uplo, A, B, beta, C)");
#endif

    cblas_dsymm
(CblasRowMajor, Side, Uplo,
                C
.GetM(), C.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetN(),
                beta
, C.GetData(), C.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const complex<float> alpha,
             
const SeldonUplo& Uplo,
             
const Matrix<complex<float>, Prop0, RowSym, Allocator0>& A,
             
const Matrix<complex<float>, Prop1, RowMajor, Allocator1>& B,
             
const complex<float> beta,
             
Matrix<complex<float>, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, uplo, A, B, beta, C)");
#endif

    cblas_csymm
(CblasRowMajor, Side, Uplo,
                C
.GetM(), C.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetN(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const complex<double> alpha,
             
const SeldonUplo& Uplo,
             
const Matrix<complex<double>, Prop0, RowSym, Allocator0>& A,
             
const Matrix<complex<double>, Prop1, RowMajor, Allocator1>& B,
             
const complex<double> beta,
             
Matrix<complex<double>, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, uplo, A, B, beta, C)");
#endif

    cblas_zsymm
(CblasRowMajor, Side, Uplo,
                C
.GetM(), C.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetN(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetN());
 
}


 
// MltAdd //
 
////////////



 
////////////
 
// MltAdd //


 
/*** ColHerm and Upper ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const complex<float> alpha,
             
const Matrix<complex<float>, Prop0, ColHerm, Allocator0>& A,
             
const Matrix<complex<float>, Prop1, ColMajor, Allocator1>& B,
             
const complex<float> beta,
             
Matrix<complex<float>, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, A, B, beta, C)");
#endif

    cblas_chemm
(CblasColMajor, Side, CblasUpper,
                C
.GetM(), C.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetM(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const complex<double> alpha,
             
const Matrix<complex<double>, Prop0, ColHerm, Allocator0>& A,
             
const Matrix<complex<double>, Prop1, ColMajor, Allocator1>& B,
             
const complex<double> beta,
             
Matrix<complex<double>, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, A, B, beta, C)");
#endif

    cblas_zhemm
(CblasColMajor, Side, CblasUpper,
                C
.GetM(), C.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetM(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetM());
 
}


 
/*** ColHerm and UpLo ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const complex<float> alpha,
             
const SeldonUplo& Uplo,
             
const Matrix<complex<float>, Prop0, ColHerm, Allocator0>& A,
             
const Matrix<complex<float>, Prop1, ColMajor, Allocator1>& B,
             
const complex<float> beta,
             
Matrix<complex<float>, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, uplo, A, B, beta, C)");
#endif

    cblas_chemm
(CblasColMajor, Side, Uplo,
                C
.GetM(), C.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetM(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const complex<double> alpha,
             
const SeldonUplo& Uplo,
             
const Matrix<complex<double>, Prop0, ColHerm, Allocator0>& A,
             
const Matrix<complex<double>, Prop1, ColMajor, Allocator1>& B,
             
const complex<double> beta,
             
Matrix<complex<double>, Prop2, ColMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, uplo, A, B, beta, C)");
#endif

    cblas_zhemm
(CblasColMajor, Side, Uplo,
                C
.GetM(), C.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetM(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetM());
 
}


 
/*** RowHerm and Upper ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const complex<float> alpha,
             
const Matrix<complex<float>, Prop0, RowHerm, Allocator0>& A,
             
const Matrix<complex<float>, Prop1, RowMajor, Allocator1>& B,
             
const complex<float> beta,
             
Matrix<complex<float>, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, A, B, beta, C)");
#endif

    cblas_chemm
(CblasRowMajor, Side, CblasUpper,
                C
.GetM(), C.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetN(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const complex<double> alpha,
             
const Matrix<complex<double>, Prop0, RowHerm, Allocator0>& A,
             
const Matrix<complex<double>, Prop1, RowMajor, Allocator1>& B,
             
const complex<double> beta,
             
Matrix<complex<double>, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, A, B, beta, C)");
#endif

    cblas_zhemm
(CblasRowMajor, Side, CblasUpper,
                C
.GetM(), C.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetN(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetN());
 
}


 
/*** RowHerm and UpLo ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const complex<float> alpha,
             
const SeldonUplo& Uplo,
             
const Matrix<complex<float>, Prop0, RowHerm, Allocator0>& A,
             
const Matrix<complex<float>, Prop1, RowMajor, Allocator1>& B,
             
const complex<float> beta,
             
Matrix<complex<float>, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, uplo, A, B, beta, C)");
#endif

    cblas_chemm
(CblasRowMajor, Side, Uplo,
                C
.GetM(), C.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetN(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1,
           
class Prop2, class Allocator2>
 
void MltAdd(const SeldonSide& Side,
             
const complex<double> alpha,
             
const SeldonUplo& Uplo,
             
const Matrix<complex<double>, Prop0, RowHerm, Allocator0>& A,
             
const Matrix<complex<double>, Prop1, RowMajor, Allocator1>& B,
             
const complex<double> beta,
             
Matrix<complex<double>, Prop2, RowMajor, Allocator2>& C)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, C, "MltAdd(side, alpha, uplo, A, B, beta, C)");
#endif

    cblas_zhemm
(CblasRowMajor, Side, Uplo,
                C
.GetM(), C.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<const void*>(B.GetData()), B.GetN(),
               
reinterpret_cast<const void*>(&beta),
               
reinterpret_cast<void*>(C.GetData()), C.GetN());
 
}


 
// MltAdd //
 
////////////



 
/////////
 
// Mlt //


 
/*** ColUpTriang, NoTrans and NonUnit ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const float alpha,
           
const Matrix<float, Prop0, ColUpTriang, Allocator0>& A,
           
Matrix<float, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, A, B)");
#endif

    cblas_strmm
(CblasColMajor, Side, CblasUpper, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const double alpha,
           
const Matrix<double, Prop0, ColUpTriang, Allocator0>& A,
           
Matrix<double, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, A, B)");
#endif

    cblas_dtrmm
(CblasColMajor, Side, CblasUpper, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const complex<float> alpha,
           
const Matrix<complex<float>, Prop0, ColUpTriang, Allocator0>& A,
           
Matrix<complex<float>, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, A, B)");
#endif

    cblas_ctrmm
(CblasColMajor, Side, CblasUpper, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<void*>(B.GetData()), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const complex<double> alpha,
           
const Matrix<complex<double>, Prop0, ColUpTriang, Allocator0>& A,
           
Matrix<complex<double>, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, A, B)");
#endif

    cblas_ztrmm
(CblasColMajor, Side, CblasUpper, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<void*>(B.GetData()), B.GetM());
 
}


 
/*** ColUpTriang ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const float alpha,
           
const SeldonTranspose& TransA,
           
const SeldonDiag& DiagA,
           
const Matrix<float, Prop0, ColUpTriang, Allocator0>& A,
           
Matrix<float, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, status, diag, A, B)");
#endif

    cblas_strmm
(CblasColMajor, Side, CblasUpper, TransA, DiagA,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const double alpha,
           
const SeldonTranspose& TransA,
           
const SeldonDiag& DiagA,
           
const Matrix<double, Prop0, ColUpTriang, Allocator0>& A,
           
Matrix<double, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, status, diag, A, B)");
#endif

    cblas_dtrmm
(CblasColMajor, Side, CblasUpper, TransA, DiagA,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const complex<float> alpha,
           
const SeldonTranspose& TransA,
           
const SeldonDiag& DiagA,
           
const Matrix<complex<float>, Prop0, ColUpTriang, Allocator0>& A,
           
Matrix<complex<float>, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, status, diag, A, B)");
#endif

    cblas_ctrmm
(CblasColMajor, Side, CblasUpper, TransA, DiagA,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<void*>(B.GetData()), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const complex<double> alpha,
           
const SeldonTranspose& TransA,
           
const SeldonDiag& DiagA,
           
const Matrix<complex<double>, Prop0, ColUpTriang, Allocator0>& A,
           
Matrix<complex<double>, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, status, diag, A, B)");
#endif

    cblas_ztrmm
(CblasColMajor, Side, CblasUpper, TransA, DiagA,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<void*>(B.GetData()), B.GetM());
 
}


 
/*** ColLoTriang, NoTrans and NonUnit ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const float alpha,
           
const Matrix<float, Prop0, ColLoTriang, Allocator0>& A,
           
Matrix<float, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, A, B)");
#endif

    cblas_strmm
(CblasColMajor, Side, CblasLower, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const double alpha,
           
const Matrix<double, Prop0, ColLoTriang, Allocator0>& A,
           
Matrix<double, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, A, B)");
#endif

    cblas_dtrmm
(CblasColMajor, Side, CblasLower, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const complex<float> alpha,
           
const Matrix<complex<float>, Prop0, ColLoTriang, Allocator0>& A,
           
Matrix<complex<float>, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, A, B)");
#endif

    cblas_ctrmm
(CblasColMajor, Side, CblasLower, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<void*>(B.GetData()), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const complex<double> alpha,
           
const Matrix<complex<double>, Prop0, ColLoTriang, Allocator0>& A,
           
Matrix<complex<double>, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, A, B)");
#endif

    cblas_ztrmm
(CblasColMajor, Side, CblasLower, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<void*>(B.GetData()), B.GetM());
 
}


 
/*** ColLoTriang ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const float alpha,
           
const SeldonTranspose& TransA,
           
const SeldonDiag& DiagA,
           
const Matrix<float, Prop0, ColLoTriang, Allocator0>& A,
           
Matrix<float, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, status, diag, A, B)");
#endif

    cblas_strmm
(CblasColMajor, Side, CblasLower, TransA, DiagA,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const double alpha,
           
const SeldonTranspose& TransA,
           
const SeldonDiag& DiagA,
           
const Matrix<double, Prop0, ColLoTriang, Allocator0>& A,
           
Matrix<double, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, status, diag, A, B)");
#endif

    cblas_dtrmm
(CblasColMajor, Side, CblasLower, TransA, DiagA,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const complex<float> alpha,
           
const SeldonTranspose& TransA,
           
const SeldonDiag& DiagA,
           
const Matrix<complex<float>, Prop0, ColLoTriang, Allocator0>& A,
           
Matrix<complex<float>, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, status, diag, A, B)");
#endif

    cblas_ctrmm
(CblasColMajor, Side, CblasLower, TransA, DiagA,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<void*>(B.GetData()), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const complex<double> alpha,
           
const SeldonTranspose& TransA,
           
const SeldonDiag& DiagA,
           
const Matrix<complex<double>, Prop0, ColLoTriang, Allocator0>& A,
           
Matrix<complex<double>, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, status, diag, A, B)");
#endif

    cblas_ztrmm
(CblasColMajor, Side, CblasLower, TransA, DiagA,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<void*>(B.GetData()), B.GetM());
 
}


 
/*** RowUpTriang, NoTrans and NonUnit ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const float alpha,
           
const Matrix<float, Prop0, RowUpTriang, Allocator0>& A,
           
Matrix<float, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, A, B)");
#endif

    cblas_strmm
(CblasRowMajor, Side, CblasUpper, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetN(), B.GetData(), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const double alpha,
           
const Matrix<double, Prop0, RowUpTriang, Allocator0>& A,
           
Matrix<double, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, A, B)");
#endif

    cblas_dtrmm
(CblasRowMajor, Side, CblasUpper, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetN(), B.GetData(), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const complex<float> alpha,
           
const Matrix<complex<float>, Prop0, RowUpTriang, Allocator0>& A,
           
Matrix<complex<float>, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, A, B)");
#endif

    cblas_ctrmm
(CblasRowMajor, Side, CblasUpper, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetN(),
               
reinterpret_cast<void*>(B.GetData()), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const complex<double> alpha,
           
const Matrix<complex<double>, Prop0, RowUpTriang, Allocator0>& A,
           
Matrix<complex<double>, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, A, B)");
#endif

    cblas_ztrmm
(CblasRowMajor, Side, CblasUpper, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetN(),
               
reinterpret_cast<void*>(B.GetData()), B.GetN());
 
}


 
/*** RowUpTriang ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const float alpha,
           
const SeldonTranspose& TransA,
           
const SeldonDiag& DiagA,
           
const Matrix<float, Prop0, RowUpTriang, Allocator0>& A,
           
Matrix<float, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, status, diag, A, B)");
#endif

    cblas_strmm
(CblasRowMajor, Side, CblasUpper, TransA, DiagA,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetN(), B.GetData(), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const double alpha,
           
const SeldonTranspose& TransA,
           
const SeldonDiag& DiagA,
           
const Matrix<double, Prop0, RowUpTriang, Allocator0>& A,
           
Matrix<double, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, status, diag, A, B)");
#endif

    cblas_dtrmm
(CblasRowMajor, Side, CblasUpper, TransA, DiagA,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetN(), B.GetData(), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const complex<float> alpha,
           
const SeldonTranspose& TransA,
           
const SeldonDiag& DiagA,
           
const Matrix<complex<float>, Prop0, RowUpTriang, Allocator0>& A,
           
Matrix<complex<float>, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, status, diag, A, B)");
#endif

    cblas_ctrmm
(CblasRowMajor, Side, CblasUpper, TransA, DiagA,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetN(),
               
reinterpret_cast<void*>(B.GetData()), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const complex<double> alpha,
           
const SeldonTranspose& TransA,
           
const SeldonDiag& DiagA,
           
const Matrix<complex<double>, Prop0, RowUpTriang, Allocator0>& A,
           
Matrix<complex<double>, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, status, diag, A, B)");
#endif

    cblas_ztrmm
(CblasRowMajor, Side, CblasUpper, TransA, DiagA,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetN(),
               
reinterpret_cast<void*>(B.GetData()), B.GetN());
 
}


 
/*** RowLoTriang, NoTrans and NonUnit ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const float alpha,
           
const Matrix<float, Prop0, RowLoTriang, Allocator0>& A,
           
Matrix<float, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, A, B)");
#endif

    cblas_strmm
(CblasRowMajor, Side, CblasLower, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetN(), B.GetData(), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const double alpha,
           
const Matrix<double, Prop0, RowLoTriang, Allocator0>& A,
           
Matrix<double, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, A, B)");
#endif

    cblas_dtrmm
(CblasRowMajor, Side, CblasLower, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetN(), B.GetData(), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const complex<float> alpha,
           
const Matrix<complex<float>, Prop0, RowLoTriang, Allocator0>& A,
           
Matrix<complex<float>, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, A, B)");
#endif

    cblas_ctrmm
(CblasRowMajor, Side, CblasLower, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetN(),
               
reinterpret_cast<void*>(B.GetData()), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const complex<double> alpha,
           
const Matrix<complex<double>, Prop0, RowLoTriang, Allocator0>& A,
           
Matrix<complex<double>, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, A, B)");
#endif

    cblas_ztrmm
(CblasRowMajor, Side, CblasLower, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetN(),
               
reinterpret_cast<void*>(B.GetData()), B.GetN());
 
}


 
/*** RowLoTriang ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const float alpha,
           
const SeldonTranspose& TransA,
           
const SeldonDiag& DiagA,
           
const Matrix<float, Prop0, RowLoTriang, Allocator0>& A,
           
Matrix<float, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, status, diag, A, B)");
#endif

    cblas_strmm
(CblasRowMajor, Side, CblasLower, TransA, DiagA,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetN(), B.GetData(), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const double alpha,
           
const SeldonTranspose& TransA,
           
const SeldonDiag& DiagA,
           
const Matrix<double, Prop0, RowLoTriang, Allocator0>& A,
           
Matrix<double, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, status, diag, A, B)");
#endif

    cblas_dtrmm
(CblasRowMajor, Side, CblasLower, TransA, DiagA,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetN(), B.GetData(), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const complex<float> alpha,
           
const SeldonTranspose& TransA,
           
const SeldonDiag& DiagA,
           
const Matrix<complex<float>, Prop0, RowLoTriang, Allocator0>& A,
           
Matrix<complex<float>, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, status, diag, A, B)");
#endif

    cblas_ctrmm
(CblasRowMajor, Side, CblasLower, TransA, DiagA,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetN(),
               
reinterpret_cast<void*>(B.GetData()), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Mlt(const SeldonSide& Side,
           
const complex<double> alpha,
           
const SeldonTranspose& TransA,
           
const SeldonDiag& DiagA,
           
const Matrix<complex<double>, Prop0, RowLoTriang, Allocator0>& A,
           
Matrix<complex<double>, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Mlt(side, alpha, status, diag, A, B)");
#endif

    cblas_ztrmm
(CblasRowMajor, Side, CblasLower, TransA, DiagA,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetN(),
               
reinterpret_cast<void*>(B.GetData()), B.GetN());
 
}


 
// Mlt //
 
/////////



 
///////////
 
// Solve //


 
/*** ColUpTriang, NoTrans and NonUnit ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const float alpha,
             
const Matrix<float, Prop0, ColUpTriang, Allocator0>& A,
             
Matrix<float, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, A, B)");
#endif

    cblas_strsm
(CblasColMajor, Side, CblasUpper, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const double alpha,
             
const Matrix<double, Prop0, ColUpTriang, Allocator0>& A,
             
Matrix<double, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, A, B)");
#endif

    cblas_dtrsm
(CblasColMajor, Side, CblasUpper, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const complex<float> alpha,
             
const Matrix<complex<float>, Prop0, ColUpTriang, Allocator0>& A,
             
Matrix<complex<float>, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, A, B)");
#endif

    cblas_ctrsm
(CblasColMajor, Side, CblasUpper, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<void*>(B.GetData()), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const complex<double> alpha,
             
const Matrix<complex<double>, Prop0, ColUpTriang, Allocator0>& A,
             
Matrix<complex<double>, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, A, B)");
#endif

    cblas_ztrsm
(CblasColMajor, Side, CblasUpper, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<void*>(B.GetData()), B.GetM());
 
}


 
/*** ColUpTriang ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const float alpha,
             
const SeldonTranspose& TransA,
             
const SeldonDiag& DiagA,
             
const Matrix<float, Prop0, ColUpTriang, Allocator0>& A,
             
Matrix<float, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, status, diag, A, B)");
#endif

    cblas_strsm
(CblasColMajor, Side, CblasUpper, TransA, DiagA,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const double alpha,
             
const SeldonTranspose& TransA,
             
const SeldonDiag& DiagA,
             
const Matrix<double, Prop0, ColUpTriang, Allocator0>& A,
             
Matrix<double, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, status, diag, A, B)");
#endif

    cblas_dtrsm
(CblasColMajor, Side, CblasUpper, TransA, DiagA,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const complex<float> alpha,
             
const SeldonTranspose& TransA,
             
const SeldonDiag& DiagA,
             
const Matrix<complex<float>, Prop0, ColUpTriang, Allocator0>& A,
             
Matrix<complex<float>, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, status, diag, A, B)");
#endif

    cblas_ctrsm
(CblasColMajor, Side, CblasUpper, TransA, DiagA,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<void*>(B.GetData()), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const complex<double> alpha,
             
const SeldonTranspose& TransA,
             
const SeldonDiag& DiagA,
             
const Matrix<complex<double>, Prop0, ColUpTriang, Allocator0>& A,
             
Matrix<complex<double>, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, status, diag, A, B)");
#endif

    cblas_ztrsm
(CblasColMajor, Side, CblasUpper, TransA, DiagA,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<void*>(B.GetData()), B.GetM());
 
}


 
/*** ColLoTriang, NoTrans and NonUnit ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const float alpha,
             
const Matrix<float, Prop0, ColLoTriang, Allocator0>& A,
             
Matrix<float, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, A, B)");
#endif

    cblas_strsm
(CblasColMajor, Side, CblasLower, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const double alpha,
             
const Matrix<double, Prop0, ColLoTriang, Allocator0>& A,
             
Matrix<double, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, A, B)");
#endif

    cblas_dtrsm
(CblasColMajor, Side, CblasLower, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const complex<float> alpha,
             
const Matrix<complex<float>, Prop0, ColLoTriang, Allocator0>& A,
             
Matrix<complex<float>, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, A, B)");
#endif

    cblas_ctrsm
(CblasColMajor, Side, CblasLower, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<void*>(B.GetData()), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const complex<double> alpha,
             
const Matrix<complex<double>, Prop0, ColLoTriang, Allocator0>& A,
             
Matrix<complex<double>, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, A, B)");
#endif

    cblas_ztrsm
(CblasColMajor, Side, CblasLower, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<void*>(B.GetData()), B.GetM());
 
}


 
/*** ColLoTriang ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const float alpha,
             
const SeldonTranspose& TransA,
             
const SeldonDiag& DiagA,
             
const Matrix<float, Prop0, ColLoTriang, Allocator0>& A,
             
Matrix<float, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, status, diag, A, B)");
#endif

    cblas_strsm
(CblasColMajor, Side, CblasLower, TransA, DiagA,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const double alpha,
             
const SeldonTranspose& TransA,
             
const SeldonDiag& DiagA,
             
const Matrix<double, Prop0, ColLoTriang, Allocator0>& A,
             
Matrix<double, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, status, diag, A, B)");
#endif

    cblas_dtrsm
(CblasColMajor, Side, CblasLower, TransA, DiagA,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetM(), B.GetData(), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const complex<float> alpha,
             
const SeldonTranspose& TransA,
             
const SeldonDiag& DiagA,
             
const Matrix<complex<float>, Prop0, ColLoTriang, Allocator0>& A,
             
Matrix<complex<float>, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, status, diag, A, B)");
#endif

    cblas_ctrsm
(CblasColMajor, Side, CblasLower, TransA, DiagA,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<void*>(B.GetData()), B.GetM());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const complex<double> alpha,
             
const SeldonTranspose& TransA,
             
const SeldonDiag& DiagA,
             
const Matrix<complex<double>, Prop0, ColLoTriang, Allocator0>& A,
             
Matrix<complex<double>, Prop1, ColMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, status, diag, A, B)");
#endif

    cblas_ztrsm
(CblasColMajor, Side, CblasLower, TransA, DiagA,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetM(),
               
reinterpret_cast<void*>(B.GetData()), B.GetM());
 
}


 
/*** RowUpTriang, NoTrans and NonUnit ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const float alpha,
             
const Matrix<float, Prop0, RowUpTriang, Allocator0>& A,
             
Matrix<float, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, A, B)");
#endif

    cblas_strsm
(CblasRowMajor, Side, CblasUpper, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetN(), B.GetData(), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const double alpha,
             
const Matrix<double, Prop0, RowUpTriang, Allocator0>& A,
             
Matrix<double, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, A, B)");
#endif

    cblas_dtrsm
(CblasRowMajor, Side, CblasUpper, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetN(), B.GetData(), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const complex<float> alpha,
             
const Matrix<complex<float>, Prop0, RowUpTriang, Allocator0>& A,
             
Matrix<complex<float>, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, A, B)");
#endif

    cblas_ctrsm
(CblasRowMajor, Side, CblasUpper, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetN(),
               
reinterpret_cast<void*>(B.GetData()), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const complex<double> alpha,
             
const Matrix<complex<double>, Prop0, RowUpTriang, Allocator0>& A,
             
Matrix<complex<double>, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, A, B)");
#endif

    cblas_ztrsm
(CblasRowMajor, Side, CblasUpper, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetN(),
               
reinterpret_cast<void*>(B.GetData()), B.GetN());
 
}


 
/*** RowUpTriang ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const float alpha,
             
const SeldonTranspose& TransA,
             
const SeldonDiag& DiagA,
             
const Matrix<float, Prop0, RowUpTriang, Allocator0>& A,
             
Matrix<float, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, status, diag, A, B)");
#endif

    cblas_strsm
(CblasRowMajor, Side, CblasUpper, TransA, DiagA,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetN(), B.GetData(), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const double alpha,
             
const SeldonTranspose& TransA,
             
const SeldonDiag& DiagA,
             
const Matrix<double, Prop0, RowUpTriang, Allocator0>& A,
             
Matrix<double, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, status, diag, A, B)");
#endif

    cblas_dtrsm
(CblasRowMajor, Side, CblasUpper, TransA, DiagA,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetN(), B.GetData(), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const complex<float> alpha,
             
const SeldonTranspose& TransA,
             
const SeldonDiag& DiagA,
             
const Matrix<complex<float>, Prop0, RowUpTriang, Allocator0>& A,
             
Matrix<complex<float>, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, status, diag, A, B)");
#endif

    cblas_ctrsm
(CblasRowMajor, Side, CblasUpper, TransA, DiagA,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetN(),
               
reinterpret_cast<void*>(B.GetData()), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const complex<double> alpha,
             
const SeldonTranspose& TransA,
             
const SeldonDiag& DiagA,
             
const Matrix<complex<double>, Prop0, RowUpTriang, Allocator0>& A,
             
Matrix<complex<double>, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, status, diag, A, B)");
#endif

    cblas_ztrsm
(CblasRowMajor, Side, CblasUpper, TransA, DiagA,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetN(),
               
reinterpret_cast<void*>(B.GetData()), B.GetN());
 
}


 
/*** RowLoTriang, NoTrans and NonUnit ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const float alpha,
             
const Matrix<float, Prop0, RowLoTriang, Allocator0>& A,
             
Matrix<float, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, A, B)");
#endif

    cblas_strsm
(CblasRowMajor, Side, CblasLower, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetN(), B.GetData(), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const double alpha,
             
const Matrix<double, Prop0, RowLoTriang, Allocator0>& A,
             
Matrix<double, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, A, B)");
#endif

    cblas_dtrsm
(CblasRowMajor, Side, CblasLower, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetN(), B.GetData(), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const complex<float> alpha,
             
const Matrix<complex<float>, Prop0, RowLoTriang, Allocator0>& A,
             
Matrix<complex<float>, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, A, B)");
#endif

    cblas_ctrsm
(CblasRowMajor, Side, CblasLower, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetN(),
               
reinterpret_cast<void*>(B.GetData()), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const complex<double> alpha,
             
const Matrix<complex<double>, Prop0, RowLoTriang, Allocator0>& A,
             
Matrix<complex<double>, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, A, B)");
#endif

    cblas_ztrsm
(CblasRowMajor, Side, CblasLower, CblasNoTrans, CblasNonUnit,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetN(),
               
reinterpret_cast<void*>(B.GetData()), B.GetN());
 
}


 
/*** RowLoTriang ***/


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const float alpha,
             
const SeldonTranspose& TransA,
             
const SeldonDiag& DiagA,
             
const Matrix<float, Prop0, RowLoTriang, Allocator0>& A,
             
Matrix<float, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, status, diag, A, B)");
#endif

    cblas_strsm
(CblasRowMajor, Side, CblasLower, TransA, DiagA,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetN(), B.GetData(), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const double alpha,
             
const SeldonTranspose& TransA,
             
const SeldonDiag& DiagA,
             
const Matrix<double, Prop0, RowLoTriang, Allocator0>& A,
             
Matrix<double, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, status, diag, A, B)");
#endif

    cblas_dtrsm
(CblasRowMajor, Side, CblasLower, TransA, DiagA,
                B
.GetM(), B.GetN(),
                alpha
, A.GetData(), A.GetN(), B.GetData(), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const complex<float> alpha,
             
const SeldonTranspose& TransA,
             
const SeldonDiag& DiagA,
             
const Matrix<complex<float>, Prop0, RowLoTriang, Allocator0>& A,
             
Matrix<complex<float>, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, status, diag, A, B)");
#endif

    cblas_ctrsm
(CblasRowMajor, Side, CblasLower, TransA, DiagA,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetN(),
               
reinterpret_cast<void*>(B.GetData()), B.GetN());
 
}


 
template <class Prop0, class Allocator0,
           
class Prop1, class Allocator1>
 
void Solve(const SeldonSide& Side,
             
const complex<double> alpha,
             
const SeldonTranspose& TransA,
             
const SeldonDiag& DiagA,
             
const Matrix<complex<double>, Prop0, RowLoTriang, Allocator0>& A,
             
Matrix<complex<double>, Prop1, RowMajor, Allocator1>& B)
 
{

#ifdef SELDON_CHECK_BOUNDS
   
CheckDim(Side, A, B, "Solve(side, alpha, status, diag, A, B)");
#endif

    cblas_ztrsm
(CblasRowMajor, Side, CblasLower, TransA, DiagA,
                B
.GetM(), B.GetN(),
               
reinterpret_cast<const void*>(&alpha),
               
reinterpret_cast<const void*>(A.GetData()), A.GetN(),
               
reinterpret_cast<void*>(B.GetData()), B.GetN());
 
}


 
// Solve //
 
///////////


} // namespace Seldon.

#define SELDON_FILE_BLAS_3_CXX
#endif