convolve.h

Go to the documentation of this file.
00001 
00015 #ifndef _DLR_NUMERIC_CONVOLVE_H_
00016 #define _DLR_NUMERIC_CONVOLVE_H_
00017 
00018 #include <dlrCommon/tags.h>
00019 #include <dlrNumeric/array1D.h>
00020 #include <dlrNumeric/convolutionStrategy.h>
00021 
00022 namespace dlr {
00023 
00024   namespace numeric {
00025 
00028     template <class Type>
00029     inline Array1D<Type>
00030     convolve(const Array1D<Type>& kernel,
00031              const Array1D<Type>& signal,
00032              ConvolutionStrategy strategy = DLR_CONVOLVE_ZERO_PAD_RESULT);
00033 
00034 
00037     template <class Type0, class Type1>
00038     inline Array1D<Type1>
00039     convolve(const Array1D<Type0>& kernel,
00040              const Array1D<Type0>& signal,
00041              type_tag<Type1> resultTag,
00042              ConvolutionStrategy strategy = DLR_CONVOLVE_ZERO_PAD_RESULT);
00043   
00044 
00047     template <class Type>
00048     inline Array1D<Type>
00049     correlate(const Array1D<Type>& kernel,
00050               const Array1D<Type>& signal,
00051               ConvolutionStrategy strategy = DLR_CONVOLVE_ZERO_PAD_RESULT);
00052 
00053 
00056     template <class Type0, class Type1>
00057     Array1D<Type1>
00058     correlate(const Array1D<Type0>& kernel,
00059               const Array1D<Type0>& signal,
00060               type_tag<Type1> resultTag,
00061               ConvolutionStrategy strategy = DLR_CONVOLVE_ZERO_PAD_RESULT);
00062   
00063   
00064   } // namespace numeric
00065 
00066 } // namespace dlr
00067 
00068 
00069 /* ======= Declarations to maintain compatibility with legacy code. ======= */
00070 
00071 namespace dlr {
00072 
00073   using numeric::convolve;
00074   using numeric::convolve;
00075   using numeric::correlate;
00076   using numeric::correlate;
00077 
00078 } // namespace dlr
00079 
00080 
00081 /* ================ Definitions follow ================ */
00082 
00083 
00084 #include <algorithm> // For std::reverse_copy()
00085 #include <dlrNumeric/convolve1D.h>
00086 
00087 namespace dlr {
00088 
00089   namespace numeric {
00090 
00092     namespace privateCode {
00093 
00094       template <class Type0, class Type1>
00095       Array1D<Type1>
00096       oldCorrelateReflectSignal(const Array1D<Type0>& kernel,
00097                                 const Array1D<Type0>& signal,
00098                                 type_tag<Type1> resultTag)
00099       {
00100         if(kernel.size() % 2 != 1) {
00101           DLR_THROW(ValueException, "correlate()",
00102                     "Argument kernel must have an odd number of elements.");
00103         }
00104         if(kernel.size() > signal.size()) {
00105           DLR_THROW(ValueException, "correlate()",
00106                     "Argument kernel must not have more elements than "
00107                     "argument signal.");
00108         }
00109         
00110         Array1D<Type1> result(kernel.size() + signal.size() - 1);
00111         for(size_t borderIndex = 0; borderIndex < kernel.size() - 1;
00112             ++borderIndex) {
00113           Type1 dotProduct0 = static_cast<Type1>(0);
00114           Type1 dotProduct1 = static_cast<Type1>(0);
00115           size_t kernelIndex = 0;
00116           size_t signalIndex = (kernel.size() - borderIndex) - 1;
00117           while(kernelIndex < kernel.size() - borderIndex - 1) {          
00118             dotProduct0 += kernel[kernelIndex] * signal[signalIndex];
00119             dotProduct1 +=
00120               kernel[(kernel.size() - kernelIndex) - 1]
00121               * signal[(signal.size() - signalIndex) - 1];
00122             ++kernelIndex;
00123             --signalIndex;
00124           }
00125           while(kernelIndex < kernel.size()) {          
00126             dotProduct0 += kernel[kernelIndex] * signal[signalIndex];
00127             dotProduct1 +=
00128               kernel[(kernel.size() - kernelIndex) - 1]
00129               * signal[(signal.size() - signalIndex) - 1];
00130             ++kernelIndex;
00131             ++signalIndex;
00132           }
00133           result[borderIndex] = dotProduct0;
00134           result[(result.size() - borderIndex) - 1] = dotProduct1;
00135         }
00136 
00137         correlate1DCommon<Type1, Type0, Type0>(
00138           kernel,
00139           signal.begin(),
00140           signal.end() - 2 * kernel.size() + 1,
00141           result.begin() + kernel.size() - 1);
00142         return result;
00143       }
00144 
00145     } // namespace privateCode
00147     
00148     template <class Type>
00149     inline Array1D<Type>
00150     convolve(const Array1D<Type>& kernel,
00151              const Array1D<Type>& signal,
00152              ConvolutionStrategy strategy)
00153     {
00154       return convolve(kernel, signal, type_tag<Type>(), strategy);
00155     }  
00156 
00157   
00158     template <class Type0, class Type1>
00159     inline Array1D<Type1>
00160     convolve(const Array1D<Type0>& kernel,
00161              const Array1D<Type0>& signal,
00162              type_tag<Type1> resultTag,
00163              ConvolutionStrategy strategy)
00164     {
00165       Array1D<Type0> reversedKernel(kernel.size());
00166       std::reverse_copy(kernel.begin(), kernel.end(), reversedKernel.begin());
00167       return correlate(reversedKernel, signal, resultTag, strategy);
00168     }
00169     
00170 
00171   
00172     template <class Type>
00173     inline Array1D<Type>
00174     correlate(const Array1D<Type>& kernel,
00175               const Array1D<Type>& signal,
00176               ConvolutionStrategy strategy)
00177     {
00178       return correlate(kernel, signal, type_tag<Type>(), strategy);
00179     }
00180 
00181 
00182     template <class Type0, class Type1>
00183     Array1D<Type1>
00184     correlate(const Array1D<Type0>& kernel,
00185               const Array1D<Type0>& signal,
00186               type_tag<Type1> resultTag,
00187               ConvolutionStrategy strategy)
00188     {
00189       switch(strategy) {
00190       case DLR_CONVOLVE_TRUNCATE_RESULT:
00191         return correlate1D<Type1>(
00192           kernel, signal, strategy, DLR_CONVOLVE_ROI_VALID);
00193         break;
00194       case DLR_CONVOLVE_ZERO_PAD_RESULT:
00195         return correlate1D<Type1>(
00196           kernel, signal, DLR_CONVOLVE_PAD_RESULT, DLR_CONVOLVE_ROI_SAME,
00197           static_cast<Type1>(0));
00198         break;
00199       case DLR_CONVOLVE_ZERO_PAD_SIGNAL:
00200       case DLR_CONVOLVE_WRAP_SIGNAL:
00201         return correlate1D<Type1>(
00202           kernel, signal, strategy, DLR_CONVOLVE_ROI_FULL);
00203         break;
00204       case DLR_CONVOLVE_REFLECT_SIGNAL:
00205         return privateCode::oldCorrelateReflectSignal(
00206           kernel, signal, type_tag<Type1>());
00207         break;
00208       default:
00209         DLR_THROW(LogicException, "correlate()",
00210                   "Illegal value for strategy argument.  "
00211                   "This function is deprecated.  "
00212                   "Please consider using convolve1D() or correlate1D() "
00213                   "instead.");
00214         break;
00215       }
00216       return Array1D<Type1>();
00217     }
00218   
00219   } // namespace numeric
00220 
00221 } // namespace dlr
00222 
00223 #endif // #ifndef _DLR_NUMERIC_CONVOLVE_H_

Generated on Wed Nov 25 00:42:41 2009 for dlrUtilities Utility Library by  doxygen 1.5.8