I have moved to a new address.
I have moved to a new address.
After reading this article about emulating templates with C macros, I implemented a small set of fixed-length container classes for primitives, with a template-like set of macros.
The macros were used to generate containers for all primitives (short, int, long, long long, char and unsigned variants, BOOL, float, double) in immutable and mutable flavors. The containers can return the primitive itself, or an autoreleased NSNumber instance that wraps the primitive. The interface for PCMutableDoubleArray, for instance, looks like this:
// Immutable interface - (id) initWithLength: (unsigned int) num; - (id) initWithLength: (unsigned int) num andDoubles: (double) double_0, ...; - (double) doubleAtIndex: (unsigned int) index; - (double*) array; - (unsigned int) count; - (unsigned int) length; - (NSNumber*) numberAtIndex: (unsigned int) index; // Mutable interface - (void) setNumber: (NSNumber*) number atIndex: (unsigned int) index; - (void) setDouble: (type) aDouble atIndex: (unsigned int) index; - (void) setDoubles: (int) length, ...; - (void) setDoublesFromArray: (PCDoubleArray*) arr;
A .zip archive of the containers is available here (BSD licensed).
Probably one of the best advantages of an interactive GUI for scientific programs is the ability to visualize data in real time. While you could as well output a full dump of your data and plot with an external program, there is great pleasure in exploring how your model reacts to mucking and futzing around with the parameter space.
In the Systemic Console program (above), I wrote a flexible Swing component for plotting. As you can see, it takes care of plotting scatter (with optional error bars) and line plots, histograms and 3D line plots. Plot styles are easy to customize and are close to most journal styles by default. The component takes care of printing, zooming, tracking the mouse pointer and has a customization panel. Writing this component myself and optimizing it for quick redrawing took quite a bit of time. The graphical performance of Swing under OS X was often under par, especially when trying to get antialiasing right. There is no built-in way to generate PDFs (I ended up using the excellent iText for that). And finally, as usual a lot of the tedium derived from Java’s verbosity. What’s available for Cocoa?
I’m still quite a way to be worrying about the UI of my new application; currently, I am mostly thinking about the overall framework, how much of it to write in C and how much to wrap in shiny Objective-C classes. However, I’ve spent a bit of time researching the current landscape of data visualization. I will survey some of the options below, along with some IMO pros/cons.
Website, Documentation, Open source
An open-source framework used by a few Mac applications. It can show line and scatter plots, and pie charts. It is very well documented and easy to use (see e.g. this tutorial at MacResearch).
Website, BSD license
I have only had time to give a cursory look to this framework, but from what I have seen from glancing at the examples and the documentation, it seems like a very complete and decently documented framework. The project is frequently updated, and there seems to be a good amount of tutorial and forum posts on Stack Overflow about it. This is mainly due to its compatibility with iOS.
Website, Free for open source projects, $400 otherwise (including in-house projects)
This is basically the full plotting component powering the excellent DataGraph. The framework is available for free for open source projects.
The philosophy is very different from the other components listed above. A plot is defined beforehand by creating a template in DataGraph, rather than programmatically in the code; this is similar to how Aqua UIs are usually serialized in nib files designed with Interface Builder rather than created programmatically. This makes setting up a static plot almost trivial. You can also connect sliders, color wells and other interface elements with plot and formula parameters extremely easily. Zooming, panning and exporting are taken care by the framework. Finally, the output quality is the same as DataGraph, and therefore excellent.
This might be easier than it looks, and is basically the path I took for the Systemic Console to get exactly the look and functionality I needed. It has the advantage of implementing exactly what you need without unwanted baggage.
An object inheriting from NSView will do its drawing in the
drawRect: method. The actual drawing can be performed using
NSBezierPaths to draw lines, ovals, rects and rounded rects with quality antialiasing. Finally, PDF creation is handled by Cocoa automatically (see, e.g., this).
NSBezierPathnot available on iOS.
This is just a quick and undoubtedly incomplete survey of options for plotting with a Cocoa view. For my project, I will probably go with #3 or #4, with Core Plot a close third and the best option for iOS development. The DataGraph framework is truly impressive for output quality and breadth of options, and trivially easy to set up for static plots.
Please let me know if there’s any library I missed in this post. You can leave a comment below or send me a message with the “Ask anything” link at the top of the blog.
-rewrite-objcoption. This simple line to allocate and initialize an
NSArraywith a few
would become something like this ungodly mess, if there were a separate “compile to C” step:Enough to bring down cdecl.
As I mentioned in my introductory post, I am working on the overall design of a native Cocoa port of the Systemic Console (currently a Java/Swing application). This involves carefully thinking about what some of the core needs will be and which of the core libraries (frameworks) will address them. Therefore, every few days I will talk briefly about what class/library I am learning for a particular section of the port, with some useful links I have perused and possibly some small snippets of code. This will also be useful to me to store my resources in a centralized place.
The lion’s share of the code resides in a “kernel” class (which delegates to a decent number of focused classes), and is dedicated to complex and not-so-complex numerical tasks, often executed in parallel. A good number of these are implemented using custom numerical routines, ThreadPoolExecutor and Apache Commons-Math.
Objective-C’s ability to interface trivially with C libraries opens up a wealth of options to choose from. GSL, for instance, has been conveniently packaged as a framework here. Mac OS X comes with the Accelerate framework preinstalled, which includes LAPACK, BLAS and a number of vectorizing operations calls. The documentation is a bit sparse for some of it; the Apple-provided PDF doc and this nice article were very helpful. SuperMegaUltraGroovy has a simple ObjC wrapper for it (SMUGMath), which I’m testing out now - seems nice so far.
I’m dipping my toes into the threading facilities provided by Cocoa, trying to do a bunch of numerical stuff in a test Foundation project. So far, it looks pretty easy. Specifically, I am using
NSOperationQueue (implemented with Grand Central Dispatch in 10.6) to submit a bunch of numerical jobs.
NSOperationQueue is supposed to figure out the best number of threads to be spawned for the available hardware, and reusing threads as possible. Each task in my test code is implemented with NSInvocationOperation, which invokes the specified
@selector, and stuffed in a
NSArray. Finally, the jobs are queued and executed using
-addOperations:waitUntilFinished: by setting the last parameter to
YES, the current thread is blocked until all operations have finished running. Setting up
NSInvocationOperations was a cinch. So far so good!
This guide from the Reference Library lists the core competencies for Cocoa. Going through them to check I understand each one of them to a good degree.