1 /*
  2  *   Copyright (c) 2007, Michael Lehn
  3  *
  4  *   All rights reserved.
  5  *
  6  *   Redistribution and use in source and binary forms, with or without
  7  *   modification, are permitted provided that the following conditions
  8  *   are met:
  9  *
 10  *   1) Redistributions of source code must retain the above copyright
 11  *      notice, this list of conditions and the following disclaimer.
 12  *   2) Redistributions in binary form must reproduce the above copyright
 13  *      notice, this list of conditions and the following disclaimer in
 14  *      the documentation and/or other materials provided with the
 15  *      distribution.
 16  *   3) Neither the name of the FLENS development group nor the names of
 17  *      its contributors may be used to endorse or promote products derived
 18  *      from this software without specific prior written permission.
 19  *
 20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 31  */
 32 
 33 #ifndef FLENS_BLAS_OPERATORS_OPMULT_TCC
 34 #define FLENS_BLAS_OPERATORS_OPMULT_TCC 1
 35 
 36 #include <cxxblas/aux/complex.h>
 37 #include <flens/blas/closures/closures.h>
 38 #include <flens/blas/level1/dot.h>
 39 #include <flens/typedefs.h>
 40 
 41 namespace flens {
 42 
 43 //-- vector-vector products ----------------------------------------------------
 44 // x^T*y
 45 template <typename VX, typename VY>
 46 typename Promotion<typename VX::Impl::ElementType,
 47                    typename VY::Impl::ElementType>::Type
 48 operator*(const Vector<VX> &x, const Vector<VY> &y)
 49 {
 50     typedef typename VX::Impl::ElementType  TX;
 51     typedef typename VY::Impl::ElementType  TY;
 52 
 53     typename Promotion<TX,TY>::Type  result;
 54     blas::dot(x.impl(), y.impl(), result);
 55     return result;
 56 }
 57 
 58 //-- scalar-vector products ----------------------------------------------------
 59 // alpha*x
 60 template <typename ALPHA, typename V>
 61 const typename RestrictTo<
 62         IsConvertible<ALPHA, typename V::Impl::ElementType>::value
 63      || IsConvertible<typename V::Impl::ElementType, ALPHA>::value,
 64         VectorClosure<OpMult, ScalarValue<ALPHA>, typename V::Impl>
 65     >::Type
 66 operator*(const ALPHA &alpha, const Vector<V> &x)
 67 {
 68     typedef VectorClosure<OpMult, ScalarValue<ALPHA>, typename V::Impl> VC;
 69     return VC(alpha, x.impl());
 70 }
 71 
 72 // x*alpha
 73 template <typename ALPHA, typename V>
 74 const typename RestrictTo<
 75         IsConvertible<ALPHA, typename V::Impl::ElementType>::value
 76      || IsConvertible<typename V::Impl::ElementType, ALPHA>::value,
 77         VectorClosure<OpMult, ScalarValue<ALPHA>, typename V::Impl>
 78     >::Type
 79 operator*(const Vector<V> &x, const ALPHA &alpha)
 80 {
 81     typedef VectorClosure<OpMult, ScalarValue<ALPHA>, typename V::Impl> VC;
 82     return VC(alpha, x.impl());
 83 }
 84 
 85 //-- scalar-matrix products ----------------------------------------------------
 86 // alpha*A
 87 template <typename ALPHA, typename M>
 88 const typename RestrictTo<
 89         IsConvertible<ALPHA, typename M::Impl::ElementType>::value ||
 90         IsConvertible<typename M::Impl::ElementType, ALPHA>::value,
 91         MatrixClosure<OpMult, ScalarValue<ALPHA>, typename M::Impl>
 92     >::Type
 93 operator*(const ALPHA &alpha, const Matrix<M> &A)
 94 {
 95     typedef MatrixClosure<OpMult, ScalarValue<ALPHA>, typename M::Impl> MC;
 96     return MC(alpha, A.impl());
 97 }
 98 
 99 // A*alpha
100 template <typename ALPHA, typename M>
101 const typename RestrictTo<
102         IsConvertible<ALPHA, typename M::Impl::ElementType>::value ||
103         IsConvertible<typename M::Impl::ElementType, ALPHA>::value,
104         MatrixClosure<OpMult, ScalarValue<ALPHA>, typename M::Impl>
105     >::Type
106 operator*(const Matrix<M> &A, const ALPHA &alpha)
107 {
108     typedef MatrixClosure<OpMult, ScalarValue<ALPHA>, typename M::Impl> MC;
109     return MC(alpha, A.impl());
110 }
111 
112 //-- matrix-vector products ----------------------------------------------------
113 // A*x
114 template <typename M, typename V>
115 const VectorClosure<OpMult,
116                     typename M::Impl,
117                     typename V::Impl>
118 operator*(const Matrix<M> &A, const Vector<V> &x)
119 {
120     typedef VectorClosure<OpMult, typename M::Impl, typename V::Impl> VC;
121     return VC(A.impl(), x.impl());
122 }
123 
124 
125 // x*A
126 template <typename M, typename V>
127 const VectorClosure<OpMult,
128                     typename V::Impl,
129                     typename M::Impl>
130 operator*(const Vector<V> &x, const Matrix<M> &A)
131 {
132     typedef VectorClosure<OpMult, typename V::Impl, typename M::Impl> VC;
133     return VC(x.impl(), A.impl());
134 }
135 
136 //-- matrix-matrix products ----------------------------------------------------
137 // A*B
138 template <typename MA, typename MB>
139 const MatrixClosure<OpMult,
140                     typename MA::Impl,
141                     typename MB::Impl>
142 operator*(const Matrix<MA> &A, const Matrix<MB> &B)
143 {
144     typedef MatrixClosure<OpMult, typename MA::Impl, typename MB::Impl> MC;
145     return MC(A.impl(), B.impl());
146 }
147 
148 
149 // namespace flens
150 
151 #endif // FLENS_BLAS_OPERATORS_OPMULT_TCC