OpenWalnut  1.4.0
WTensorMeta.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WTENSORMETA_H
00026 #define WTENSORMETA_H
00027 
00028 #include <vector> // for size_t
00029 
00030 #include <boost/mpl/bool.hpp>
00031 
00032 // forward declaration
00033 template< typename Data_T, std::size_t k, std::size_t n, std::size_t N, std::size_t m >
00034 struct WRecursiveTensorEvaluation;
00035 
00036 /**
00037  * Multiplies gradient components and divides by multiplicities.
00038  *
00039  * This essentailly calls WRecursiveTensorEvaluation< ... >s evaluate function N times.
00040  *
00041  * If IterEnd equals boost::mpl::bool_< false >, iteration is aborted.
00042  */
00043 template< typename IterEnd, typename Data_T, std::size_t k, std::size_t i, std::size_t N >
00044 struct WRecursiveTensorEvaluationLoop
00045 {
00046     /**
00047      * Multiply gradient components and divide by multiplicities.
00048      *
00049      * \param tens A pointer to the tensor components.
00050      * \param grad The gradient to evaluate the function at.
00051      * \param w The result up to now.
00052      *
00053      * \return The result.
00054      */
00055     static inline Data_T evaluate( Data_T const*& tens, Data_T const* grad, Data_T w )
00056     {
00057         return WRecursiveTensorEvaluation< Data_T, k - 1, i, N, 1 >::evaluate( tens, grad, w * grad[ i ] )
00058                + WRecursiveTensorEvaluationLoop< boost::mpl::bool_< ( i + 1 < N ) >, Data_T, k, i + 1, N >::evaluate( tens, grad, w );
00059     }
00060 };
00061 
00062 /**
00063  * Specialization for boost::mpl::bool_< false >, aborts iteration.
00064  */
00065 template< typename Data_T, std::size_t k, std::size_t i, std::size_t N >
00066 struct WRecursiveTensorEvaluationLoop< boost::mpl::bool_< false >, Data_T, k, i, N >
00067 {
00068     /**
00069      * Does nothing.
00070      *
00071      * \return 0
00072      */
00073     static inline Data_T evaluate( Data_T const*&, Data_T const*, Data_T )
00074     {
00075         return 0.0;
00076     }
00077 };
00078 
00079 /**
00080  * Recursive evaluation of a spherical function for a gradient.
00081  */
00082 template< typename Data_T, std::size_t k, std::size_t n, std::size_t N, std::size_t m >
00083 struct WRecursiveTensorEvaluation
00084 {
00085     /**
00086      * Multiply gradient components and divide by multiplicities.
00087      *
00088      * \param tens A pointer to the tensor components.
00089      * \param grad The gradient to evaluate the function at.
00090      * \param w The result up to now.
00091      *
00092      * \return The result.
00093      */
00094     static inline Data_T evaluate( Data_T const*& tens, Data_T const* grad, Data_T w )
00095     {
00096         Data_T ret = WRecursiveTensorEvaluation< Data_T, k - 1, n, N, m + 1 >::evaluate( tens, grad, w * grad[ n ] / ( m + 1 ) );
00097         return ret + WRecursiveTensorEvaluationLoop< boost::mpl::bool_< ( n + 1 < N ) >, Data_T, k, n + 1, N >::evaluate( tens, grad, w );
00098     }
00099 };
00100 
00101 /**
00102  * Recursive evaluation of a spherical function for a gradient.
00103  */
00104 template< typename Data_T, std::size_t n, std::size_t N, std::size_t m >
00105 struct WRecursiveTensorEvaluation< Data_T, 0, n, N, m >
00106 {
00107     /**
00108      * Multiply the accumulated weight by the tensor component.
00109      *
00110      * \param tens A pointer to the tensor components.
00111      * \param w The result up to now.
00112      *
00113      * \return The result.
00114      */
00115     static inline Data_T evaluate( Data_T const*& tens, Data_T const*, Data_T w )
00116     {
00117         return w * *( tens++ );
00118     }
00119 };
00120 
00121 #endif  // WTENSORMETA_H