Skip to content
Why is a raven like a writing desk?

Thoughts both confusing and enlightening.

Why is a raven like a writing desk?

Thoughts both confusing and enlightening.

Exercising Ranges (part 7)

elbeno, 1 July, 20151 July, 2015

(Start at the beginning of the series if you want more context.)

Calculus operations

It’s relatively simple to do differentiation and integration of power series, since they’re just regular polynomial-style. No trigonometric identities, logarithms or other tricky integrals here. Just the plain rule for positive powers of x. For differentiation, we have:

[latex]\frac{d}{dx}kx^{n} = knx^{n-1}[/latex]

Which is straightforwardly expressed with ranges: we simply take the tail of the power series and pairwise multiply with n, the power:

template 
auto differentiate(Rng&& r)
{
  return ranges::view::zip_with(
      std::multiplies<>(),
      ranges::view::iota(1),
      ranges::view::tail(std::forward(r)));
}

Integration is almost as easy. The fly in the ointment is that up until now, we have been working entirely with integers, or whatever underlying arithmetic type is present in the range. Here is where Haskell wins with its built in rational numbers and polymorphic fromIntegral for conversion from integral types. Integration brings division into the picture:

[latex]\int_{}{} kx^n dx = \frac{kx^{n+1}}{n+1}[/latex]

Which means we need to turn a range of ints into a range of floats or doubles. Or use a rational number library. But anyway, sweeping these concerns under the rug, the actual code for integration is as easy as that for differentiation:

template 
auto integrate(Rng&& r)
{
  return ranges::view::concat(
      ranges::view::single(0),
      ranges::view::zip_with(
          [] (auto x, auto y) { return (float)x / (float)y; },
          std::forward(r),
          ranges::view::iota(1)));
}

We prepend a zero as the constant of integration.

Calculus: in real life, more difficult than arithmetic, but with ranges, considerably easier. That was a welcome break from extreme mental effort. In the next part, I round out my range experiments for now, with a look at a couple more functions from the Haskell Prelude.

C++ Programming

Post navigation

Previous post
Next post

Related Posts

Profiling with SBCL

29 February, 200829 February, 2008

My Bézier curve code was not optimal, so I decided to learn how to profile with SBCL. In particular, I was not yet doing a binary search of the sampled points, neither was I doing an interpolation to recover the parameter t. Finally, I was sampling the curve at a…

Read More

Do-notation can be misleading

13 August, 201430 June, 2015

Consider the following function: oddness :: Maybe Int oddness = do let a = Just 1 :: Maybe Int b >= \b -> return b And recall the definition of (>>=) for Maybe: instance Monad Maybe where (Just x) >>= k = k x Nothing >>= _ = Nothing So…

Read More

A problem with C++ lambdas?

18 February, 201530 June, 2015

C++ lambdas are wonderful for all sorts of reasons (especially with their C++14-and-beyond power). But I’ve run into a problem that I can’t think of a good way around yet. If you’re up to date with C++, of course you know that rvalue references and move semantics are a major…

Read More

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

©2026 Why is a raven like a writing desk? | WordPress Theme by SuperbThemes