OpenWalnut
1.4.0
|
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