diff --git a/examples.md b/examples.md index 4629893..35ca4fa 100644 --- a/examples.md +++ b/examples.md @@ -32,6 +32,7 @@ for plotting or rendering graphics. - [Ranges](examples/ranges.html) - [Scans and reductions](examples/scan-reduce.html) - [Parametric polymorphism](examples/parametric-polymorphism.html) +- [Exclusive scans](examples/exclusive-scan.html) - [Gather and scatter](examples/gather-and-scatter.html) - [Pipe operators](examples/piping.html) - [Complex ranges](examples/complex-ranges.html) @@ -76,6 +77,7 @@ for plotting or rendering graphics. - [AD with dual numbers](examples/dual-numbers.html) - [Variance](examples/variance.html) - [Matching parentheses](examples/parens.html) +- [Evaluating polynomials](examples/polynomials.html) # Automatic differentiation diff --git a/examples/exclusive-scan.fut b/examples/exclusive-scan.fut new file mode 100644 index 0000000..32daf9b --- /dev/null +++ b/examples/exclusive-scan.fut @@ -0,0 +1,16 @@ +-- # Exclusive scans +-- +-- There are two common ways of specifying [scans](scan-reduce.html): +-- inclusive and exclusive. In an inclusive scan, element *i* of the +-- output includes element *i* of the input, while for an exclusive +-- scan it only goes up to *i-1*. The `scan` functon in Futhark is an +-- inclusive scan, but it is easy to define an exclusive one: + +def exscan f ne xs = + map2 (\i x -> if i == 0 then ne else x) + (indices xs) + (rotate (-1) (scan f ne xs)) + +-- ## See also +-- +-- [Evaluating polynomials](polynomials.html). diff --git a/examples/polynomials.fut b/examples/polynomials.fut new file mode 100644 index 0000000..4ef05d0 --- /dev/null +++ b/examples/polynomials.fut @@ -0,0 +1,23 @@ +-- # Evaluating polynomials +-- +-- A polynomial of the *n*th degree comprises *n* coefficients and can +-- be evaluated at a specific value *x* as follows: + +entry poly as x = + f64.sum (map2 (*) as (map (x**) (map f64.i64 (indices as)))) + +-- [Horner's method](https://en.wikipedia.org/wiki/Horner%27s_method) +-- is a well-known technique for evaluating polynomials using fewer +-- multiplications (in particular, avoiding the use of the power +-- operation). While normally expressed sequentially, it can also be +-- implemented in Futhark using an [exclusive +-- scan](exclusive-scan.html): + +import "exclusive-scan" + +entry horner as x = + f64.sum (map2 (*) as (exscan (*) 1 (map (const x) as))) + +-- In most cases, the additional overhead of manifesting the result of +-- the `scan` exceeds the savings from not evaluating `**`, so `poly` +-- is often fastest.