#include #include #include // calculate first order forward difference // requires: // * InputIterator is an input iterator // * OutputIterator is an output iterator // * The value type of InputIterator is copy-constructible and assignable // * The value type of InputIterator supports operator - // * The result type of operator- is assignable to the value_type of OutputIterator // returns: The iterator following the output sequence template OutputIterator forward_difference(InputIterator first, InputIterator last, OutputIterator dest) { // special case: for empty sequence, do nothing if (first == last) return dest; typedef typename std::iterator_traits::value_type value_type; value_type temp = *first++; while (first != last) { value_type temp2 = *first++; *dest++ = temp2 - temp; temp = temp2; } return dest; } // calculate n-th order forward difference. // requires: // * InputIterator is an input iterator // * OutputIterator is an output iterator // * The value type of InputIterator is copy-constructible and assignable // * The value type of InputIterator supports operator - // * The result type of operator- is assignable to the value_type of InputIterator // * The result type of operator- is assignable to the value_type of OutputIterator // * order >= 0 // returns: The iterator following the output sequence template OutputIterator nth_forward_difference(int order, InputIterator first, InputIterator last, OutputIterator dest) { // special case: If order == 0, just copy input to output if (order == 0) return std::copy(first, last, dest); // second special case: If order == 1, just forward to the first-order function if (order == 1) return forward_difference(first, last, dest); // intermediate results are stored in a vector typedef typename std::iterator_traits::value_type value_type; std::vector temp_storage; // fill the vector with the result of the first order forward difference forward_difference(first, last, std::back_inserter(temp_storage)); // the next n-2 iterations work directly on the vector typename std::vector::iterator begin = temp_storage.begin(), end = temp_storage.end(); for (int i = 1; i < order-1; ++i) end = forward_difference(begin, end, begin); // the final iteration writes directly to the output iterator return forward_difference(begin, end, dest); } // example usage code #include int main() { double array[10] = { 90.0, 47.0, 58.0, 29.0, 22.0, 32.0, 55.0, 5.0, 55.0, 73.0 }; // this stores the results in the vector dest std::vector dest; nth_forward_difference(1, array, array+10, std::back_inserter(dest)); // output dest std::copy(dest.begin(), dest.end(), std::ostream_iterator(std::cout, " ")); std::cout << std::endl; // however, the results can also be output as they are calculated nth_forward_difference(2, array, array+10, std::ostream_iterator(std::cout, " ")); std::cout << std::endl; nth_forward_difference(9, array, array+10, std::ostream_iterator(std::cout, " ")); std::cout << std::endl; nth_forward_difference(10, array, array+10, std::ostream_iterator(std::cout, " ")); std::cout << std::endl; nth_forward_difference(0, array, array+10, std::ostream_iterator(std::cout, " ")); std::cout << std::endl; // finally, the results can also be written into the original array // (which of course destroys the original content) double* end = nth_forward_difference(3, array, array+10, array); for (double* p = array; p < end; ++p) std::cout << *p << " "; std::cout << std::endl; return 0; }