views:

104

answers:

3

I'm working on a project where I need to store a matrix of numbers indexed by two string keys. The matrix is not jagged, i.e. if a column key exists for any row then it should exist for all rows. Similarly, if a row key exists for any column then it should exist for all columns.

The obvious way to express this is with an associative array of associative arrays, but this is both awkward and inefficient, and it doesn't enforce the non-jaggedness property. Do any popular programming languages provide an associative matrix either built into the language or as part of their standard libraries? If so, how do they work, both at the API and implementation level? I'm using Python and D for this project, but examples in other languages would still be useful because I would be able to look at the API and figure out the best way to implement something similar in Python or D.

+3  A: 

Why not just use a standard matrix, but then have two dictionaries - one that converts the row keys to row indices and one that converts the columns keys to columns indices. You could make your own structure that would work this way fairly easily I think. You just make a class that contains the matrix and the two dictionaries and go from there.

Justin Peel
A: 

In Python you could have a dict indexed by a tuple of two strings, e.g

>>> d = {}
>>> d["foo","bar"] = 10
>>> d
{('foo', 'bar'): 10}

I am not sure what "enforce non-jaggedness" means for you, but you could either use a defaultdict to return a default value for entries that have not been explicitly set, or initialise the dict with the a known value:

>>> xkeys = "abcdef"
>>> ykeys = "xyz"
>>> d = dict(((x,y), 0) for x in xkeys for y in ykeys)
>>> d
{('b', 'y'): 0, ('a', 'z'): 0, ('b', 'x'): 0, ('e', 'y'): 0, ('a', 'x'): 0, ('f', 'z'): 0, ('a', 'y'): 0, ('f', 'y'): 0, ('d', 'y'): 0, ('f', 'x'): 0, ('d', 'x'): 0, ('e', 'x'): 0, ('e', 'z'): 0, ('c', 'x'): 0, ('d', 'z'): 0, ('c', 'y'): 0, ('c', 'z'): 0, ('b', 'z'): 0}

If you want to enforce that only keys in a known set are allowed then I suggest subclassing dict to add the validation.

Dave Kirby
Yeah, I don't really know Python that well. I was not aware you could do this, though it makes sense in hindsight given that you're basically using tuples as a key.
dsimcha
this works great, but it will use more memory to store the keys which I thought was part of what you didn't want. However, it should be a little faster than the method I suggested which will require hash table look-ups to find the matrix indices before accessing the matrix. Speed or space: that's the question.
Justin Peel
@Justin: It's a nice idea, but I'm hoping for a better answer. Ideally I'd like a "real" matrix, where I can get all rows for a single column, or all columns for a single row, etc., not just a workaround.
dsimcha
A: 

the larry module for python was recently released. i believe it does what you want.

Autoplectic