SciRuby/nmatrix — pull request #80 by cjfuller (2013-04-20 22:46:08+00:00)
Title: Fixes for issue51-related elementwise operations on dense matrix slices.

I've added some specs for testing the slice by reference related problems reported in issue #51 (both for the transpose as well as the elementwise operation problems I later reported), and added a fix to dense matrix storage to fix the elementwise operations.

Issue #51 appears to occur because a number of operations work directly on the stored elements of a NMatrix. For a matrix slice by reference, the elements storage is the same as the original matrix, so these operations just start operating on the elements from the beginning of the unsliced matrix, not the sliced one.

Since the `nm_dense_storage_pos` function operates correctly on sliced and non-sliced matrices, my fix was to add an inverse function, `nm_dense_storage_coords` that would take the index from the element storage in the result of the operation and compute the multi-dimensional coordinates from it; and then to use the `nm_dense_storage_pos` to get the correct offset in the element storage for the sliced matrix.

I haven't fixed the transpose problem yet as it is somewhat more complicated. I think it would no longer be possible to use the memcpy-based generic transpose function on slice-by-reference matrices. Doing the coordinate transformations for every element of a transpose could also presumably add a substantial performance hit on the transpose in some cases (not sure whether this would matter in real-world applications or not). This could be bypassed for instance by adding a value to the storage object that indicates whether it is a slice by reference, and doing the faster or slower version accordingly.

There may be better, more general solutions, but I think they might be somewhat more perturbative than the fixes in this pull request, and involve adding extra fields, etc. to storage objects, so I'll take discussion of this to the mailing list before proceeding.