Friday, 27 September 2013

F# for Visualization 0.7 released

A new version of F# for Visualization has been released that boasts the following features:
  1. Easier to use than ever before!
  2. Contour plots.
  3. Interactive charts: pan and zoom with the mouse.
  4. New API.
  5. Programmatically close chart windows.

To use F# for Visualization in a script, simply put the DLL in the same directory as the .fsx file and reference it in the script like this:

  #r "FSharpForVisualization"

The following namespace contains lots of helpful functions that make F# for Visualization extremely easy to use:

  open FlyingFrog.FSharpForVisualization

For example, you can plot a sine wave like this:

  plot sin

Note that the chart can be dragged and zoomed using the mouse.

Heuristics are used to guess ranges when none are supplied:

  plot sqrt

Ranges over x are easily supplied like this:

  plot(atan, (0, 10))

Ranges over y can be supplied in a similar way:

  plot(atan, (-10, 10), (-1.5, 1.5))

Note that ranges need not be given as floating point numbers but can, in fact, be any numeric type.

We can also label the axes like this:

  plot(atan, (-10, 10), (-1.5, 1.5), ("x", "atan(x)"))

Run-time type information is used to determine the kind of chart used to visualize a function. For example, a function of two variables is automatically visualized as a contour plot:

  plot atan2

Functions of the type Complexfloat are also visualized as contour plots, this time with default axis labels. For example, the function Im(√z):

  open System.Numerics
  plot(fun z -> Complex.Sqrt(z).Imaginary)

The plot function can also be used to plot series. For example, sequences of numbers are taken to be y coordinates:

  plot [for i in 0..10 -> i*i]

Sequences of pairs of numbers are x,y coordinates:

  plot [for i in 0..10 -> i*i, i]

Sequences of such sequences are assumed to be multiple series:

  plot[[for i in 0..10 -> i*i, i]; [for i in 0..10 -> i*i*i, i]]

Predator-prey population evolution may then be visualized like this:

  let g, k, t = 0.02, 5e2, 1500

  let evolve (r, f) _ =
    let dtrf = 1e-4 * r * f
    r + (1.0 - r/k)*r*g - dtrf, dtrf + (1.0 - g)*f

  plot(Seq.scan evolve (50.0, 10.0) [1..t], ("Rabbits", "Foxes"))

The plot function returns an object with SaveAsPng and Close members that allow the visualization to be saved programmatically and closed:

  let window = plot floor

  window.SaveAsPng "TheFloorFunction.png"


Charts support typeset mathematics for both labels and annotations. For example, plot the sinc function and label the axes accordingly:

  open FlyingFrog.Controls
  open FlyingFrog.Graphics.Typeset.Math
  open FlyingFrog.Interactive

  let sinc x = sin x / x

  let g = Plot([Function sinc], (-10.0, 10.0))
  g.Labels <- font="" math="">"x", Fraction(Row[Text "sin"; math "(x)"], math "x"))

Annotate a point on the graph:

  #r "PresentationCore.dll"
  #r "PresentationFramework.dll"
  #r "WindowsBase.dll"

  open System.Windows
  open FlyingFrog.Graphics.Scene
  open FlyingFrog.Graphics.Typeset

  let pi = System.Math.PI
  g.Data <- data="" o:p="" pi="" sinc="" unction="">
  g.Epilog <- font="" label="" math="" ow="" scene="">"("; Fraction(Greek.pi, math "2"); math ",";
                              Fraction(math "2", Greek.pi); math ")"]),
                    0.003, Point(pi/2.0, sinc(pi/2.0)), Vector(-1.2, -1.2))

Although F# for Visualization does not depend upon F# for Numerics or the F# PowerPack it can consume types from those libraries. For example, the following computes the 5x5 Hilbert matrix using arbitrary-precision rational elements:

  #r "FSharp.PowerPack.dll"

  open Microsoft.FSharp.Math

  let A =
      [ for i in 0N..4N ->
          [ for j in 0N..4N ->
              1N / (i + j + 1N) ] ]

Just as our plot function attempts to chart any value of any type so the view function attempts to visualize any value of any type, such as our Hilbert matrix:

  view A

or even a typeset mathematical matrix equation:

  view(Row[math A; Symbols.Times; math A; math "="; math(A*A)])

The ability to visualize values of F# types as typeset mathematics so easily is invaluable for interactive technical computing.

F# for Visualization also provides an easy-to-use API for general 2D vector graphics. Vector graphics are styled by a sequence of strokes or fills colored with WPF brushes:

  open System.Windows.Media
  open FlyingFrog.Graphics.Style

  let styles =
    [ Stroke(Brushes.Red, {Width = 0.001}) ]

The geometry of a shape is a sequence of contours that may be closed or open (only closed contours will be filled):

  open FlyingFrog.Graphics.Contour

  let geometry =
    let n = 50
    [ for i in 0 .. n do
        for j in 0 .. 1 do
          let x, y = float i / float n, float j
            Contour.Open(Point(x, y), [lineTo(y, 1.0 - x)]) ]

A vector graphics scene may contain shapes, groups of scenes, transformed scenes and clipped scenes:

  open FlyingFrog.Graphics.Scene

  let scene = Shape(styles, geometry)

The view function visualizes the vector graphics scene:

  view scene
The scene may also be visualized on a pair of axes by making it the epilog of an empty plot:

  Plot([], (0., 1.), (0., 1.), Epilog=scene)

F# for Visualization also does 3D graphics.

  open FlyingFrog.Graphics3D
  open FlyingFrog.Graphics3D.Scene3D

A Mesh describes a geometry and a Shape3D combines a mesh with a WPF Brush in order to represent a colored 3D object as a piece of scene graph. For example, the following creates a white icosahedron:

  let scene3d = Shape3D(Polyhedra.icosahedron, Brushes.White)

The same "view" function can be used to visualize 3D objects:

  view scene3d

F# for Visualization is currently available for just £49 under our beta release scheme. This latest release brings F# for Visualization much closer to it's first full release whereupon the price will increase. So why wait? Order your copy of F# for Visualization today!

No comments: